diff options
author | Andrew Tridgell <tridge@samba.org> | 2004-11-03 10:09:48 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:05:23 -0500 |
commit | dde07058075d357cfdc63624c8dcaa67ebd40add (patch) | |
tree | c3f29090e37f1bc103a3d6051e708d1ebbe305a5 /source4/lib/messaging | |
parent | 90a8c4acc7e673e6439197776d19cc4b095ac322 (diff) | |
download | samba-dde07058075d357cfdc63624c8dcaa67ebd40add.tar.gz samba-dde07058075d357cfdc63624c8dcaa67ebd40add.tar.xz samba-dde07058075d357cfdc63624c8dcaa67ebd40add.zip |
r3507: - added deferred replies on sharing violation in pvfs open. The
deferred reply is short-circuited immediately when the file is
closed by another user, allowing it to be opened by the waiting user.
- added a sane set of timeval manipulation routines
- converted all the events code and code that uses it to use struct
timeval instead of time_t, which allows for microsecond resolution
instead of 1 second resolution. This was needed for doing the pvfs
deferred open code, and is why the patch is so big.
(This used to be commit 0d51511d408d91eb5f68a35e980e0875299b1831)
Diffstat (limited to 'source4/lib/messaging')
-rw-r--r-- | source4/lib/messaging/messaging.c | 51 |
1 files changed, 41 insertions, 10 deletions
diff --git a/source4/lib/messaging/messaging.c b/source4/lib/messaging/messaging.c index f862b2d505..041554a7c0 100644 --- a/source4/lib/messaging/messaging.c +++ b/source4/lib/messaging/messaging.c @@ -29,6 +29,9 @@ /* change the message version with any incompatible changes in the protocol */ #define MESSAGING_VERSION 1 +/* the number of microseconds to backoff in retrying to send a message */ +#define MESSAGING_BACKOFF 250000 + struct messaging_context { servid_t server_id; struct socket_context *sock; @@ -119,7 +122,7 @@ static void messaging_dispatch(struct messaging_context *msg, struct messaging_r handle IO for a single message */ static void messaging_recv_handler(struct event_context *ev, struct fd_event *fde, - time_t t, uint16_t flags) + struct timeval t, uint16_t flags) { struct messaging_rec *rec = fde->private; struct messaging_context *msg = rec->msg; @@ -200,7 +203,7 @@ static int rec_destructor(void *ptr) handle a new incoming connection */ static void messaging_listen_handler(struct event_context *ev, struct fd_event *fde, - time_t t, uint16_t flags) + struct timeval t, uint16_t flags) { struct messaging_context *msg = fde->private; struct messaging_rec *rec; @@ -272,7 +275,7 @@ void messaging_deregister(struct messaging_context *msg, uint32_t msg_type, void handle IO for sending a message */ static void messaging_send_handler(struct event_context *ev, struct fd_event *fde, - time_t t, uint16_t flags) + struct timeval t, uint16_t flags) { struct messaging_rec *rec = fde->private; NTSTATUS status; @@ -324,19 +327,33 @@ static void messaging_send_handler(struct event_context *ev, struct fd_event *fd /* + wrapper around socket_connect with raised privileges +*/ +static NTSTATUS try_connect(struct messaging_rec *rec) +{ + NTSTATUS status; + void *priv = root_privileges(); + status = socket_connect(rec->sock, NULL, 0, rec->path, 0, 0); + talloc_free(priv); + return status; +} + + +/* when the servers listen queue is full we use this to backoff the message */ -static void messaging_backoff_handler(struct event_context *ev, struct timed_event *te, time_t t) +static void messaging_backoff_handler(struct event_context *ev, struct timed_event *te, + struct timeval t) { struct messaging_rec *rec = te->private; struct messaging_context *msg = rec->msg; NTSTATUS status; struct fd_event fde; - status = socket_connect(rec->sock, NULL, 0, rec->path, 0, 0); + status = try_connect(rec); if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { /* backoff again */ - te->next_event = t+1; + te->next_event = timeval_add(&t, 0, MESSAGING_BACKOFF); return; } @@ -356,7 +373,7 @@ static void messaging_backoff_handler(struct event_context *ev, struct timed_eve talloc_set_destructor(rec, rec_destructor); - messaging_send_handler(msg->event.ev, rec->fde, 0, EVENT_FD_WRITE); + messaging_send_handler(msg->event.ev, rec->fde, timeval_zero(), EVENT_FD_WRITE); } @@ -396,11 +413,11 @@ NTSTATUS messaging_send(struct messaging_context *msg, servid_t server, uint32_t rec->path = messaging_path(rec, server); - status = socket_connect(rec->sock, NULL, 0, rec->path, 0, 0); + status = try_connect(rec); if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { /* backoff on this message - the servers listen queue is full */ struct timed_event te; - te.next_event = time(NULL)+1; + te.next_event = timeval_current_ofs(0, MESSAGING_BACKOFF); te.handler = messaging_backoff_handler; te.private = rec; event_add_timed(msg->event.ev, &te); @@ -421,11 +438,25 @@ NTSTATUS messaging_send(struct messaging_context *msg, servid_t server, uint32_t talloc_set_destructor(rec, rec_destructor); - messaging_send_handler(msg->event.ev, rec->fde, 0, EVENT_FD_WRITE); + messaging_send_handler(msg->event.ev, rec->fde, timeval_zero(), EVENT_FD_WRITE); return NT_STATUS_OK; } +/* + Send a message to a particular server, with the message containing a single pointer +*/ +NTSTATUS messaging_send_ptr(struct messaging_context *msg, servid_t server, + uint32_t msg_type, void *ptr) +{ + DATA_BLOB blob; + + blob.data = (void *)&ptr; + blob.length = sizeof(void *); + + return messaging_send(msg, server, msg_type, &blob); +} + /* destroy the messaging context |