summaryrefslogtreecommitdiff
path: root/source4/lib/messaging/messaging.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2004-11-03 10:09:48 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:05:23 -0500
commitdde07058075d357cfdc63624c8dcaa67ebd40add (patch)
treec3f29090e37f1bc103a3d6051e708d1ebbe305a5 /source4/lib/messaging/messaging.c
parent90a8c4acc7e673e6439197776d19cc4b095ac322 (diff)
downloadsamba-dde07058075d357cfdc63624c8dcaa67ebd40add.tar.gz
samba-dde07058075d357cfdc63624c8dcaa67ebd40add.tar.bz2
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/messaging.c')
-rw-r--r--source4/lib/messaging/messaging.c51
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