1
0
mirror of https://github.com/samba-team/samba.git synced 2025-07-28 11:42:03 +03:00

Added new message_send_pid() code that uses tdb append to reduce locking

contention on the messaging tdb.
Jeremy.
This commit is contained in:
Jeremy Allison
-
parent 724cefabb0
commit ee0ceeff99

View File

@ -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 kbuf;
TDB_DATA dbuf; TDB_DATA dbuf;
TDB_DATA old_dbuf;
struct message_rec rec; struct message_rec rec;
void *p; char *ptr;
struct message_rec prec;
/* /*
* Doing kill with a non-positive pid causes messages to be * 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); kbuf = message_key_pid(pid);
/* lock the record for the destination */ dbuf.dptr = (void *)malloc(len + sizeof(rec));
tdb_chainlock(tdb, kbuf); if (!dbuf.dptr)
return False;
dbuf = tdb_fetch(tdb, kbuf); memcpy(dbuf.dptr, &rec, sizeof(rec));
if (len > 0)
memcpy((void *)((char*)dbuf.dptr+sizeof(rec)), buf, len);
if (!dbuf.dptr) { dbuf.dsize = len + sizeof(rec);
/* its a new record */
p = (void *)malloc(len + sizeof(rec));
if (!p)
goto failed;
memcpy(p, &rec, sizeof(rec)); if (duplicates_allowed) {
if (len > 0)
memcpy((void *)((char*)p+sizeof(rec)), buf, len);
dbuf.dptr = p; /* If duplicates are allowed we can just append the message and return. */
dbuf.dsize = len + sizeof(rec);
tdb_store(tdb, kbuf, dbuf, TDB_REPLACE); /* lock the record for the destination */
SAFE_FREE(p); tdb_chainlock(tdb, kbuf);
goto ok; tdb_append(tdb, kbuf, dbuf);
tdb_chainunlock(tdb, kbuf);
SAFE_FREE(dbuf.dptr);
errno = 0; /* paranoia */
return message_notify(pid);
} }
if (!duplicates_allowed) { /* lock the record for the destination */
char *ptr; tdb_chainlock(tdb, kbuf);
struct message_rec prec; old_dbuf = tdb_fetch(tdb, kbuf);
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 (!old_dbuf.dptr) {
if (!len || (len && !memcmp( ptr + sizeof(rec), buf, len))) { /* its a new record */
DEBUG(10,("message_send_pid: discarding duplicate message.\n"));
SAFE_FREE(dbuf.dptr); tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
tdb_chainunlock(tdb, kbuf); tdb_chainunlock(tdb, kbuf);
return True;
} SAFE_FREE(dbuf.dptr);
errno = 0; /* paranoia */
return message_notify(pid);
}
/* 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 */ /* 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); tdb_append(tdb, kbuf, dbuf);
memcpy((void *)((char*)p+dbuf.dsize), &rec, sizeof(rec));
if (len > 0)
memcpy((void *)((char*)p+dbuf.dsize+sizeof(rec)), buf, len);
SAFE_FREE(dbuf.dptr);
dbuf.dptr = p;
dbuf.dsize += len + sizeof(rec);
tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
SAFE_FREE(dbuf.dptr);
ok:
tdb_chainunlock(tdb, kbuf); tdb_chainunlock(tdb, kbuf);
SAFE_FREE(old_dbuf.dptr);
SAFE_FREE(dbuf.dptr);
errno = 0; /* paranoia */ errno = 0; /* paranoia */
return message_notify(pid); return message_notify(pid);
failed:
tdb_chainunlock(tdb, kbuf);
SAFE_FREE(dbuf.dptr);
errno = 0; /* paranoia */
return False;
} }
/**************************************************************************** /****************************************************************************