From: Art Cancro Date: Sun, 21 Mar 2004 22:32:24 +0000 (+0000) Subject: * room_ops.c: increased the thread safety of cgetfloor() X-Git-Tag: v7.86~5513 X-Git-Url: https://code.citadel.org/?a=commitdiff_plain;h=4f17bebc9e09e72864ad64b0677bf526c9cb5cd9;p=citadel.git * room_ops.c: increased the thread safety of cgetfloor() * housekeeping.c: check floor reference counts in two passes instead of trying to manipulate multiple tables in O^2 --- diff --git a/citadel/ChangeLog b/citadel/ChangeLog index 8f8749044..90c622f90 100644 --- a/citadel/ChangeLog +++ b/citadel/ChangeLog @@ -1,4 +1,9 @@ $Log$ + Revision 614.90 2004/03/21 22:32:24 ajc + * room_ops.c: increased the thread safety of cgetfloor() + * housekeeping.c: check floor reference counts in two passes instead of + trying to manipulate multiple tables in O^2 + Revision 614.89 2004/03/21 17:14:46 error * stress.c: Fixed. Now properly spawns threads and stresses out your favorite Citadel server by simulating large numbers of really active @@ -5565,3 +5570,4 @@ Sat Jul 11 00:20:48 EDT 1998 Nathan Bryant Fri Jul 10 1998 Art Cancro * Initial CVS import + diff --git a/citadel/housekeeping.c b/citadel/housekeeping.c index c60bcbf94..da86e19c3 100644 --- a/citadel/housekeeping.c +++ b/citadel/housekeeping.c @@ -90,33 +90,43 @@ void check_sched_shutdown(void) { /* * Check (and fix) floor reference counts. This doesn't need to be done * very often, since the counts should remain correct during normal operation. - * NOTE: this function pair should ONLY be called during startup. It is NOT - * thread safe. */ void check_ref_counts_backend(struct ctdlroom *qrbuf, void *data) { - struct floor flbuf; - getfloor(&flbuf, qrbuf->QRfloor); - ++flbuf.f_ref_count; - flbuf.f_flags = flbuf.f_flags | QR_INUSE; - putfloor(&flbuf, qrbuf->QRfloor); + int *new_refcounts; + + new_refcounts = (int *) data; + + ++new_refcounts[(int)qrbuf->QRfloor]; } void check_ref_counts(void) { struct floor flbuf; int a; + int new_refcounts[MAXFLOORS]; + lprintf(CTDL_DEBUG, "Checking floor reference counts\n"); for (a=0; a 0) { + flbuf.f_flags = flbuf.f_flags | QR_INUSE; + } + else { + flbuf.f_flags = flbuf.f_flags & ~QR_INUSE; + } + lputfloor(&flbuf, a); + lprintf(9, "Floor %d: %d rooms\n", a, new_refcounts[a]); + } } /* diff --git a/citadel/room_ops.c b/citadel/room_ops.c index 2b80cabae..242025627 100644 --- a/citadel/room_ops.c +++ b/citadel/room_ops.c @@ -333,17 +333,31 @@ void lgetfloor(struct floor *flbuf, int floor_num) struct floor *cgetfloor(int floor_num) { static int initialized = 0; int i; + int fetch_new = 0; + struct floor *fl = NULL; + begin_critical_section(S_FLOORCACHE); if (initialized == 0) { for (i=0; i= 5) { fl = cgetfloor(extract_int(args, 4)); - if ((fl->f_flags & F_INUSE) == 0) { + if (fl == NULL) { + cprintf("%d Invalid floor number.\n", + ERROR + INVALID_FLOOR_OPERATION); + return; + } + else if ((fl->f_flags & F_INUSE) == 0) { cprintf("%d Invalid floor number.\n", ERROR + INVALID_FLOOR_OPERATION); return; diff --git a/citadel/server.h b/citadel/server.h index c72f849f1..8c42ec21c 100644 --- a/citadel/server.h +++ b/citadel/server.h @@ -215,6 +215,7 @@ enum { S_NETCONFIGS, S_PUBLIC_CLIENTS, S_LDAP, + S_FLOORCACHE, MAX_SEMAPHORES };