diff options
-rw-r--r-- | source3/lib/g_lock.c | 42 |
1 files changed, 31 insertions, 11 deletions
diff --git a/source3/lib/g_lock.c b/source3/lib/g_lock.c index 378e464b5c..dfbcf8445c 100644 --- a/source3/lib/g_lock.c +++ b/source3/lib/g_lock.c @@ -22,6 +22,7 @@ #include "librpc/gen_ndr/messaging.h" #include "ctdbd_conn.h" #include "../lib/util/select.h" +#include "system/select.h" static NTSTATUS g_lock_force_unlock(struct g_lock_ctx *ctx, const char *name, struct server_id pid); @@ -335,11 +336,9 @@ NTSTATUS g_lock_lock(struct g_lock_ctx *ctx, const char *name, timeout_end = timeval_sum(&time_now, &timeout); while (true) { -#ifdef CLUSTER_SUPPORT - fd_set _r_fds; -#endif - fd_set *r_fds = NULL; - int max_fd = 0; + struct pollfd *pollfds; + int num_pollfds; + int saved_errno; int ret; struct timeval timeout_remaining, select_timeout; @@ -387,15 +386,27 @@ NTSTATUS g_lock_lock(struct g_lock_ctx *ctx, const char *name, * events here but have to handcode a timeout. */ + /* + * We allocate 2 entries here. One is needed anyway for + * sys_poll and in the clustering case we might have to add + * the ctdb fd. This avoids the realloc then. + */ + pollfds = TALLOC_ARRAY(talloc_tos(), struct pollfd, 2); + if (pollfds == NULL) { + status = NT_STATUS_NO_MEMORY; + break; + } + num_pollfds = 1; + #ifdef CLUSTER_SUPPORT if (lp_clustering()) { struct ctdbd_connection *conn; conn = messaging_ctdbd_connection(); - r_fds = &_r_fds; - FD_ZERO(r_fds); - max_fd = ctdbd_conn_get_fd(conn); - FD_SET(max_fd, r_fds); + pollfds[0].fd = ctdbd_conn_get_fd(conn); + pollfds[0].events = POLLIN|POLLHUP; + + num_pollfds += 1; } #endif @@ -406,8 +417,17 @@ NTSTATUS g_lock_lock(struct g_lock_ctx *ctx, const char *name, select_timeout = timeval_min(&select_timeout, &timeout_remaining); - ret = sys_select(max_fd + 1, r_fds, NULL, NULL, - &select_timeout); + ret = sys_poll(pollfds, num_pollfds, + timeval_to_msec(select_timeout)); + + /* + * We're not *really interested in the actual flags. We just + * need to retry this whole thing. + */ + saved_errno = errno; + TALLOC_FREE(pollfds); + errno = saved_errno; + if (ret == -1) { if (errno != EINTR) { DEBUG(1, ("error calling select: %s\n", |