- use the tdb_chainlock_mark() call to allow us to guarantee forward progress in the ctdb_lockwait code
{
ctdb_reqid_remove(client->ctdb, client->client_id);
client->ctdb->status.num_clients--;
- close(client->fd);
- client->fd = -1;
return 0;
}
ctdb->ev = event_context_init(NULL);
- fde = event_add_fd(ctdb->ev, ctdb, fd[0], EVENT_FD_READ, ctdb_read_from_parent, &fd[0]);
- fde = event_add_fd(ctdb->ev, ctdb, ctdb->daemon.sd, EVENT_FD_READ, ctdb_accept_client, ctdb);
+ fde = event_add_fd(ctdb->ev, ctdb, fd[0], EVENT_FD_READ|EVENT_FD_AUTOCLOSE, ctdb_read_from_parent, &fd[0]);
+ fde = event_add_fd(ctdb->ev, ctdb, ctdb->daemon.sd, EVENT_FD_READ|EVENT_FD_AUTOCLOSE, ctdb_accept_client, ctdb);
ctdb_main_loop(ctdb);
return 0;
talloc_set_destructor(domain_socket_name, unlink_destructor);
ctdb->ev = event_context_init(NULL);
- fde = event_add_fd(ctdb->ev, ctdb, ctdb->daemon.sd, EVENT_FD_READ,
+ fde = event_add_fd(ctdb->ev, ctdb, ctdb->daemon.sd, EVENT_FD_READ|EVENT_FD_AUTOCLOSE,
ctdb_accept_client, ctdb);
ctdb_main_loop(ctdb);
queue->fde = NULL;
if (fd != -1) {
- queue->fde = event_add_fd(queue->ctdb->ev, queue, fd, EVENT_FD_READ,
+ queue->fde = event_add_fd(queue->ctdb->ev, queue, fd, EVENT_FD_READ|EVENT_FD_AUTOCLOSE,
queue_io_handler, queue);
if (queue->fde == NULL) {
return -1;
struct lockwait_handle {
struct ctdb_context *ctdb;
+ struct ctdb_db_context *ctdb_db;
struct fd_event *fde;
int fd[2];
pid_t child;
void *private_data;
void (*callback)(void *);
+ TDB_DATA key;
struct timeval start_time;
};
void (*callback)(void *) = h->callback;
void *p = h->private_data;
pid_t child = h->child;
+ TDB_DATA key = h->key;
+ struct tdb_context *tdb = h->ctdb_db->ltdb->tdb;
+ TALLOC_CTX *tmp_ctx = talloc_new(ev);
+
+ talloc_free(fde);
+
+ key.dptr = talloc_memdup(tmp_ctx, key.dptr, key.dsize);
+
talloc_set_destructor(h, NULL);
- close(h->fd[0]);
ctdb_latency(&h->ctdb->status.max_lockwait_latency, h->start_time);
h->ctdb->status.pending_lockwait_calls--;
- talloc_free(h);
+
+ tdb_chainlock_mark(tdb, key);
callback(p);
+ tdb_chainlock_unmark(tdb, key);
+
+ kill(child, SIGKILL);
waitpid(child, NULL, 0);
+ talloc_free(tmp_ctx);
}
static int lockwait_destructor(struct lockwait_handle *h)
{
h->ctdb->status.pending_lockwait_calls--;
- close(h->fd[0]);
kill(h->child, SIGKILL);
waitpid(h->child, NULL, 0);
return 0;
ctdb_db->ctdb->status.lockwait_calls++;
ctdb_db->ctdb->status.pending_lockwait_calls++;
- if (!(result = talloc_zero(ctdb_db, struct lockwait_handle))) {
+ if (!(result = talloc_zero(private_data, struct lockwait_handle))) {
ctdb_db->ctdb->status.pending_lockwait_calls--;
return NULL;
}
result->callback = callback;
result->private_data = private_data;
result->ctdb = ctdb_db->ctdb;
+ result->ctdb_db = ctdb_db;
+ result->key = key;
if (result->child == 0) {
+ char c = 0;
close(result->fd[0]);
- /*
- * Do we need a tdb_reopen here?
- */
tdb_chainlock(ctdb_db->ltdb->tdb, key);
+ write(result->fd[1], &c, 1);
+ pause();
_exit(0);
}
talloc_set_destructor(result, lockwait_destructor);
result->fde = event_add_fd(ctdb_db->ctdb->ev, result, result->fd[0],
- EVENT_FD_READ, lockwait_handler,
+ EVENT_FD_READ|EVENT_FD_AUTOCLOSE, lockwait_handler,
(void *)result);
if (result->fde == NULL) {
talloc_free(result);
{
struct lock_fetch_state *state = talloc_get_type(p, struct lock_fetch_state);
state->recv_pkt(state->recv_context, (uint8_t *)state->hdr, state->hdr->length);
- talloc_free(state);
DEBUG(2,(__location__ " PACKET REQUEUED\n"));
}
return 0;
}
- state = talloc(ctdb_db, struct lock_fetch_state);
+ state = talloc(hdr, struct lock_fetch_state);
state->ctdb = ctdb_db->ctdb;
state->hdr = hdr;
state->recv_pkt = recv_pkt;
*/
static int traverse_local_destructor(struct ctdb_traverse_local_handle *h)
{
- close(h->fd[0]);
kill(h->child, SIGKILL);
waitpid(h->child, NULL, 0);
return 0;