summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2003-01-11 00:17:37 +0000
committerJeremy Allison <jra@samba.org>2003-01-11 00:17:37 +0000
commit82b41dca9d0030cc54ef8865d4a5e5f9377c46fc (patch)
tree9b1f07675a8546ad3a5b80702c7b71ea88377999
parent8e7dfa50b03139227bf1c14cddc6de3ebabcabc3 (diff)
downloadsamba-82b41dca9d0030cc54ef8865d4a5e5f9377c46fc.tar.gz
samba-82b41dca9d0030cc54ef8865d4a5e5f9377c46fc.tar.bz2
samba-82b41dca9d0030cc54ef8865d4a5e5f9377c46fc.zip
Added new message_send_pid() code that uses tdb append to reduce locking
contention on the messaging tdb. Jeremy. (This used to be commit 5b8cf0810a7297f239b35c93ec50d20f1eed793b)
-rw-r--r--source3/lib/messages.c109
1 files changed, 55 insertions, 54 deletions
diff --git a/source3/lib/messages.c b/source3/lib/messages.c
index 555a55569e..38c3c411d4 100644
--- a/source3/lib/messages.c
+++ b/source3/lib/messages.c
@@ -176,8 +176,10 @@ BOOL message_send_pid(pid_t pid, int msg_type, const void *buf, size_t len,
{
TDB_DATA kbuf;
TDB_DATA dbuf;
+ TDB_DATA old_dbuf;
struct message_rec rec;
- void *p;
+ char *ptr;
+ struct message_rec prec;
/*
* Doing kill with a non-positive pid causes messages to be
@@ -194,78 +196,77 @@ BOOL message_send_pid(pid_t pid, int msg_type, const void *buf, size_t len,
kbuf = message_key_pid(pid);
+ dbuf.dptr = (void *)malloc(len + sizeof(rec));
+ if (!dbuf.dptr)
+ return False;
+
+ memcpy(dbuf.dptr, &rec, sizeof(rec));
+ if (len > 0)
+ memcpy((void *)((char*)dbuf.dptr+sizeof(rec)), buf, len);
+
+ dbuf.dsize = len + sizeof(rec);
+
+ if (duplicates_allowed) {
+
+ /* If duplicates are allowed we can just append the message and return. */
+
+ /* lock the record for the destination */
+ tdb_chainlock(tdb, kbuf);
+ tdb_append(tdb, kbuf, dbuf);
+ tdb_chainunlock(tdb, kbuf);
+
+ SAFE_FREE(dbuf.dptr);
+ errno = 0; /* paranoia */
+ return message_notify(pid);
+ }
+
/* lock the record for the destination */
tdb_chainlock(tdb, kbuf);
+ old_dbuf = tdb_fetch(tdb, kbuf);
- dbuf = tdb_fetch(tdb, kbuf);
-
- if (!dbuf.dptr) {
+ if (!old_dbuf.dptr) {
/* its a new record */
- p = (void *)malloc(len + sizeof(rec));
- if (!p)
- goto failed;
- memcpy(p, &rec, sizeof(rec));
- if (len > 0)
- memcpy((void *)((char*)p+sizeof(rec)), buf, len);
-
- dbuf.dptr = p;
- dbuf.dsize = len + sizeof(rec);
tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
- SAFE_FREE(p);
- goto ok;
+ tdb_chainunlock(tdb, kbuf);
+
+ SAFE_FREE(dbuf.dptr);
+ errno = 0; /* paranoia */
+ return message_notify(pid);
}
- if (!duplicates_allowed) {
- char *ptr;
- struct message_rec prec;
-
- for(ptr = (char *)dbuf.dptr; ptr < dbuf.dptr + dbuf.dsize; ) {
- /*
- * First check if the message header matches, then, if it's a non-zero
- * sized message, check if the data matches. If so it's a duplicate and
- * we can discard it. JRA.
- */
-
- if (!memcmp(ptr, &rec, sizeof(rec))) {
- if (!len || (len && !memcmp( ptr + sizeof(rec), buf, len))) {
- DEBUG(10,("message_send_pid: discarding duplicate message.\n"));
- SAFE_FREE(dbuf.dptr);
- tdb_chainunlock(tdb, kbuf);
- return True;
- }
+ /* Not a new record. Check for duplicates. */
+
+ for(ptr = (char *)old_dbuf.dptr; ptr < old_dbuf.dptr + old_dbuf.dsize; ) {
+ /*
+ * First check if the message header matches, then, if it's a non-zero
+ * sized message, check if the data matches. If so it's a duplicate and
+ * we can discard it. JRA.
+ */
+
+ if (!memcmp(ptr, &rec, sizeof(rec))) {
+ if (!len || (len && !memcmp( ptr + sizeof(rec), buf, len))) {
+ tdb_chainunlock(tdb, kbuf);
+ DEBUG(10,("message_send_pid: discarding duplicate message.\n"));
+ SAFE_FREE(dbuf.dptr);
+ SAFE_FREE(old_dbuf.dptr);
+ return True;
}
- memcpy(&prec, ptr, sizeof(prec));
- ptr += sizeof(rec) + prec.len;
}
+ memcpy(&prec, ptr, sizeof(prec));
+ ptr += sizeof(rec) + prec.len;
}
/* we're adding to an existing entry */
- p = (void *)malloc(dbuf.dsize + len + sizeof(rec));
- if (!p)
- goto failed;
- memcpy(p, dbuf.dptr, dbuf.dsize);
- memcpy((void *)((char*)p+dbuf.dsize), &rec, sizeof(rec));
- if (len > 0)
- memcpy((void *)((char*)p+dbuf.dsize+sizeof(rec)), buf, len);
+ tdb_append(tdb, kbuf, dbuf);
+ tdb_chainunlock(tdb, kbuf);
- SAFE_FREE(dbuf.dptr);
- dbuf.dptr = p;
- dbuf.dsize += len + sizeof(rec);
- tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
+ SAFE_FREE(old_dbuf.dptr);
SAFE_FREE(dbuf.dptr);
- ok:
- tdb_chainunlock(tdb, kbuf);
errno = 0; /* paranoia */
return message_notify(pid);
-
- failed:
- tdb_chainunlock(tdb, kbuf);
- SAFE_FREE(dbuf.dptr);
- errno = 0; /* paranoia */
- return False;
}
/****************************************************************************