lease->object_ids[lease->nobject_ids++] = connector->connector_id;
lease->is_granted = false;
+ lease->lease_fd = -1;
return lease;
assert(lm);
for (int i = 0; i < lm->nleases; i++) {
- lm_lease_revoke(lm, (struct lease_handle *)lm->leases[i]);
+ struct lease_handle *lease_handle = &lm->leases[i]->base;
+ lm_lease_revoke(lm, lease_handle);
+ lm_lease_close(lease_handle);
lease_free(lm->leases[i]);
}
return -1;
}
- lease->lease_fd =
+ int lease_fd =
drmModeCreateLease(lm->drm_fd, lease->object_ids,
lease->nobject_ids, 0, &lease->lessee_id);
- if (lease->lease_fd < 0) {
+ if (lease_fd < 0) {
ERROR_LOG("drmModeCreateLease failed on lease %s: %s\n",
lease->base.name, strerror(errno));
return -1;
}
lease->is_granted = true;
- return lease->lease_fd;
+
+ int old_lease_fd = lease->lease_fd;
+ lease->lease_fd = lease_fd;
+
+ if (old_lease_fd >= 0)
+ close_after_lease_transition(lease, old_lease_fd);
+
+ return lease_fd;
}
int lm_lease_transfer(struct lm *lm, struct lease_handle *handle)
if (!lease->is_granted)
return -1;
- int old_lease_fd = dup(lease->lease_fd);
-
lm_lease_revoke(lm, handle);
if (lm_lease_grant(lm, handle) < 0) {
- close(old_lease_fd);
+ lm_lease_close(handle);
return -1;
}
- close_after_lease_transition(lease, old_lease_fd);
return lease->lease_fd;
}
drmModeRevokeLease(lm->drm_fd, lease->lessee_id);
cancel_lease_transition_thread(lease);
- close(lease->lease_fd);
lease->is_granted = false;
}
+
+void lm_lease_close(struct lease_handle *handle)
+{
+ assert(handle);
+
+ struct lease *lease = (struct lease *)handle;
+ close(lease->lease_fd);
+ lease->lease_fd = -1;
+}
int lm_lease_grant(struct lm *lm, struct lease_handle *lease_handle);
int lm_lease_transfer(struct lm *lm, struct lease_handle *lease_handle);
void lm_lease_revoke(struct lm *lm, struct lease_handle *lease_handle);
+void lm_lease_close(struct lease_handle *lease_handle);
#endif
request = parse_client_request(sock);
if (request < 0 && (ev.events & POLLHUP))
- request = LS_REQ_RELEASE_LEASE;
+ request = LS_REQ_CLIENT_DISCONNECT;
struct ls_client *client = sock->client;
struct ls_server *server = client->serv;
enum ls_req_type {
LS_REQ_GET_LEASE,
LS_REQ_RELEASE_LEASE,
+ LS_REQ_CLIENT_DISCONNECT,
};
struct ls_req {
"Options:\n"
"-h, --help \tPrint this help\n"
"-v, --verbose \tEnable verbose debug messages\n"
- "-t, --lease-transfer \tAllow lease transfter to new clients\n",
+ "-t, --lease-transfer \tAllow lease transfter to new clients\n"
+ "-k, --keep-on-crash \tDon't close lease on client crash\n",
progname);
}
-const char *opts = "vth";
+const char *opts = "vtkh";
const struct option options[] = {
{"help", no_argument, NULL, 'h'},
{"verbose", no_argument, NULL, 'v'},
{"lease-transfer", no_argument, NULL, 't'},
+ {"keep-on-crash", no_argument, NULL, 'k'},
{NULL, 0, NULL, 0},
};
bool debug_log = false;
bool can_transfer_leases = false;
+ bool keep_on_crash = false;
int c;
while ((c = getopt_long(argc, argv, opts, options, NULL)) != -1) {
case 't':
can_transfer_leases = true;
break;
+ case 'k':
+ keep_on_crash = true;
+ break;
case 'h':
ret = EXIT_SUCCESS;
/* fall through */
break;
}
case LS_REQ_RELEASE_LEASE:
+ case LS_REQ_CLIENT_DISCONNECT:
ls_disconnect_client(ls, req.client);
req.lease_handle->user_data = NULL;
lm_lease_revoke(lm, req.lease_handle);
+
+ if (!keep_on_crash || req.type == LS_REQ_RELEASE_LEASE)
+ lm_lease_close(req.lease_handle);
+
break;
default:
ERROR_LOG("Internal error: Invalid lease request\n");