You can subscribe to this list here.
2005 |
Jan
|
Feb
(32) |
Mar
(56) |
Apr
(92) |
May
(39) |
Jun
(226) |
Jul
(98) |
Aug
(66) |
Sep
|
Oct
(153) |
Nov
(43) |
Dec
(42) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2006 |
Jan
(97) |
Feb
(141) |
Mar
(147) |
Apr
(80) |
May
(51) |
Jun
(93) |
Jul
(88) |
Aug
(50) |
Sep
(179) |
Oct
(48) |
Nov
(82) |
Dec
(71) |
2007 |
Jan
(42) |
Feb
(46) |
Mar
(123) |
Apr
(21) |
May
(139) |
Jun
(59) |
Jul
(34) |
Aug
(57) |
Sep
(47) |
Oct
(137) |
Nov
(49) |
Dec
(12) |
2008 |
Jan
(10) |
Feb
(8) |
Mar
(63) |
Apr
(17) |
May
(34) |
Jun
(38) |
Jul
(16) |
Aug
(62) |
Sep
(9) |
Oct
(121) |
Nov
(38) |
Dec
(4) |
2009 |
Jan
|
Feb
(11) |
Mar
(9) |
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2010 |
Jan
|
Feb
|
Mar
(4) |
Apr
(10) |
May
(1) |
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2011 |
Jan
(1) |
Feb
(1) |
Mar
(3) |
Apr
(2) |
May
|
Jun
|
Jul
|
Aug
(3) |
Sep
(2) |
Oct
(1) |
Nov
|
Dec
(12) |
2012 |
Jan
(26) |
Feb
(1) |
Mar
(15) |
Apr
(1) |
May
(1) |
Jun
(7) |
Jul
(2) |
Aug
|
Sep
(1) |
Oct
(52) |
Nov
(8) |
Dec
(25) |
2013 |
Jan
(35) |
Feb
(14) |
Mar
(10) |
Apr
(10) |
May
(29) |
Jun
(16) |
Jul
(5) |
Aug
(8) |
Sep
(8) |
Oct
(6) |
Nov
(1) |
Dec
(3) |
2014 |
Jan
(16) |
Feb
(13) |
Mar
(5) |
Apr
(9) |
May
(21) |
Jun
(6) |
Jul
(5) |
Aug
(2) |
Sep
(59) |
Oct
(115) |
Nov
(122) |
Dec
(45) |
2015 |
Jan
(31) |
Feb
(32) |
Mar
(19) |
Apr
(25) |
May
(3) |
Jun
(4) |
Jul
(18) |
Aug
(3) |
Sep
(23) |
Oct
(11) |
Nov
(17) |
Dec
(12) |
2016 |
Jan
(20) |
Feb
(27) |
Mar
(20) |
Apr
(40) |
May
(35) |
Jun
(48) |
Jul
(44) |
Aug
(51) |
Sep
(18) |
Oct
(42) |
Nov
(39) |
Dec
(29) |
2017 |
Jan
(37) |
Feb
(34) |
Mar
(20) |
Apr
(37) |
May
(10) |
Jun
(2) |
Jul
(14) |
Aug
(15) |
Sep
(25) |
Oct
(29) |
Nov
(15) |
Dec
(29) |
2018 |
Jan
(5) |
Feb
(15) |
Mar
(6) |
Apr
(20) |
May
(39) |
Jun
(39) |
Jul
(17) |
Aug
(20) |
Sep
(10) |
Oct
(17) |
Nov
(20) |
Dec
(8) |
2019 |
Jan
(28) |
Feb
(21) |
Mar
(13) |
Apr
(44) |
May
(44) |
Jun
(28) |
Jul
(51) |
Aug
(30) |
Sep
(7) |
Oct
(20) |
Nov
(8) |
Dec
(21) |
2020 |
Jan
(27) |
Feb
(5) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Vlad S. <ser...@us...> - 2006-01-12 01:18:06
|
Update of /cvsroot/naviserver/naviserver In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6172 Modified Files: ChangeLog Log Message: See ChangeLog for more info Index: ChangeLog =================================================================== RCS file: /cvsroot/naviserver/naviserver/ChangeLog,v retrieving revision 1.269 retrieving revision 1.270 diff -C2 -d -r1.269 -r1.270 *** ChangeLog 11 Jan 2006 10:40:33 -0000 1.269 --- ChangeLog 12 Jan 2006 01:17:56 -0000 1.270 *************** *** 1,2 **** --- 1,13 ---- + 2006-01-11 Vlad Seryakov <ser...@us...> + + * nsd/driver.c: + * nsd.nsd.c: + * nsd/tclcmds.c: Added spooler support which handles + upload process in separate thread. During the uploading new command + ns_upload_stats is available which accepts full url with query + parametrs of the uploading connection. On uploading finish, + statistics is cleared from the memory. Spooler can be disabled + using ns_param spooler false in the nssock section of nsd.tcl. + 2006-01-11 Zoran Vasiljevic <vas...@us...> |
From: Vlad S. <ser...@us...> - 2006-01-12 01:18:06
|
Update of /cvsroot/naviserver/naviserver/nsd In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6172/nsd Modified Files: driver.c nsd.h tclcmds.c Log Message: See ChangeLog for more info Index: tclcmds.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/tclcmds.c,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** tclcmds.c 30 Dec 2005 11:07:34 -0000 1.28 --- tclcmds.c 12 Jan 2006 01:17:57 -0000 1.29 *************** *** 196,200 **** NsTclWriteContentObjCmd, NsTclWriteFpObjCmd, ! NsTclWriteObjCmd; extern Tcl_CmdProc --- 196,201 ---- NsTclWriteContentObjCmd, NsTclWriteFpObjCmd, ! NsTclWriteObjCmd, ! NsTclUploadStatsObjCmd; extern Tcl_CmdProc *************** *** 441,444 **** --- 442,447 ---- {"nsv_unset", NULL, NsTclNsvUnsetObjCmd}, + {"ns_upload_stats", NULL, NsTclUploadStatsObjCmd}, + /* * Add more server Tcl commands here. Index: driver.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/driver.c,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** driver.c 10 Jan 2006 12:43:35 -0000 1.28 --- driver.c 12 Jan 2006 01:17:57 -0000 1.29 *************** *** 45,48 **** --- 45,49 ---- #define SOCK_READY 0 #define SOCK_MORE 1 + #define SOCK_SPOOL 2 #define SOCK_ERROR (-1) *************** *** 78,81 **** --- 79,85 ---- } ServerMap; [...1086 lines suppressed...] + */ + + if (trigger) { + SockTrigger(spoolerPipe[1]); + } + return 1; + } + + Sock *SockSpoolPop(void) + { + Sock *sockPtr = 0; + + Ns_MutexLock(&spoolerLock); + sockPtr = spoolerSockPtr; + if (spoolerSockPtr) { + spoolerSockPtr = spoolerSockPtr->nextPtr; + } + Ns_MutexUnlock(&spoolerLock); + return sockPtr; + } Index: nsd.h =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/nsd.h,v retrieving revision 1.43 retrieving revision 1.44 diff -C2 -d -r1.43 -r1.44 *** nsd.h 4 Jan 2006 10:15:52 -0000 1.43 --- nsd.h 12 Jan 2006 01:17:57 -0000 1.44 *************** *** 361,364 **** --- 361,365 ---- int maxheaders; /* Maximum number of request headers. */ int readahead; /* Maximum request size in memory. */ + int uploadsize; /* Minimum upload size for statistics tracking. */ unsigned int loggingFlags; /* Logging control flags */ *************** *** 398,401 **** --- 399,408 ---- size_t tsize; + struct { + char *url; + unsigned long size; + unsigned long length; + } upload; + } Sock; |
From: Zoran V. <vas...@us...> - 2006-01-11 10:40:41
|
Update of /cvsroot/naviserver/naviserver/nsd In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11326/nsd Modified Files: set.c Log Message: Fixed off-by-one error in Ns_SetDelete Index: set.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/set.c,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** set.c 4 Aug 2005 21:54:26 -0000 1.5 --- set.c 11 Jan 2006 10:40:33 -0000 1.6 *************** *** 519,527 **** ns_free(set->fields[index].name); ns_free(set->fields[index].value); for (i = index; i < set->size; ++i) { set->fields[i].name = set->fields[i + 1].name; set->fields[i].value = set->fields[i + 1].value; } - --set->size; } } --- 519,527 ---- ns_free(set->fields[index].name); ns_free(set->fields[index].value); + --set->size; for (i = index; i < set->size; ++i) { set->fields[i].name = set->fields[i + 1].name; set->fields[i].value = set->fields[i + 1].value; } } } |
From: Zoran V. <vas...@us...> - 2006-01-11 10:40:41
|
Update of /cvsroot/naviserver/naviserver In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11326 Modified Files: ChangeLog Log Message: Fixed off-by-one error in Ns_SetDelete Index: ChangeLog =================================================================== RCS file: /cvsroot/naviserver/naviserver/ChangeLog,v retrieving revision 1.268 retrieving revision 1.269 diff -C2 -d -r1.268 -r1.269 *** ChangeLog 10 Jan 2006 12:43:35 -0000 1.268 --- ChangeLog 11 Jan 2006 10:40:33 -0000 1.269 *************** *** 1,2 **** --- 1,7 ---- + 2006-01-11 Zoran Vasiljevic <vas...@us...> + + * nsd/set.c (Ns_SetDelete): fixed off-by-one error when + compacting the set after element deletion. + 2006-01-10 Zoran Vasiljevic <vas...@us...> |
From: Zoran V. <vas...@us...> - 2006-01-10 12:43:43
|
Update of /cvsroot/naviserver/naviserver/nsd In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32658/nsd Modified Files: driver.c Log Message: Added some clarifying comments Index: driver.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/driver.c,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** driver.c 7 Jan 2006 22:26:31 -0000 1.27 --- driver.c 10 Jan 2006 12:43:35 -0000 1.28 *************** *** 895,898 **** --- 895,908 ---- sockPtr = nextPtr; } + + /* + * Hint: NsQueueConn may fail to queue a certain + * socket to the designated connection queue. + * In such case, ALL ready sockets will be put on + * the waiting list until the next interation, + * regardless of which connection queue they are + * to be queued. + */ + while (sockPtr != NULL) { nextPtr = sockPtr->nextPtr; *************** *** 934,938 **** * Queue the socket immediately if request is provided */ ! n = (*sockPtr->drvPtr->proc)(DriverAccept, (Ns_Sock*)sockPtr, 0, 0); if (n == NS_OK && sockPtr->reqPtr) { if (!SetServer(sockPtr)) { --- 944,949 ---- * Queue the socket immediately if request is provided */ ! n = (*sockPtr->drvPtr->proc)(DriverAccept, ! (Ns_Sock*)sockPtr, 0, 0); if (n == NS_OK && sockPtr->reqPtr) { if (!SetServer(sockPtr)) { |
From: Zoran V. <vas...@us...> - 2006-01-10 12:43:43
|
Update of /cvsroot/naviserver/naviserver In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32658 Modified Files: ChangeLog Log Message: Added some clarifying comments Index: ChangeLog =================================================================== RCS file: /cvsroot/naviserver/naviserver/ChangeLog,v retrieving revision 1.267 retrieving revision 1.268 diff -C2 -d -r1.267 -r1.268 *** ChangeLog 7 Jan 2006 22:26:31 -0000 1.267 --- ChangeLog 10 Jan 2006 12:43:35 -0000 1.268 *************** *** 1,2 **** --- 1,6 ---- + 2006-01-10 Zoran Vasiljevic <vas...@us...> + + * nsd/driver.c (DriverThread): Added some clarifying comments + 2006-01-07 Stephen Deasey <sd...@us...> |
From: Stephen D. <sd...@us...> - 2006-01-07 22:26:39
|
Update of /cvsroot/naviserver/naviserver/nsd In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29551/nsd Modified Files: driver.c Log Message: * nsd/driver.c (DriverThread): Add Push() macro to clarify list processing of sockets and drivers. Index: driver.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/driver.c,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** driver.c 12 Nov 2005 20:50:33 -0000 1.26 --- driver.c 7 Jan 2006 22:26:31 -0000 1.27 *************** *** 93,96 **** --- 93,97 ---- static void SockTimeout(Sock *sockPtr, Ns_Time *nowPtr, int timeout); static int SetServer(Sock *sockPtr); + #define Push(x, xs) ((x)->nextPtr = (xs), (xs) = (x)) /* *************** *** 721,729 **** nextDrvPtr = drvPtr->nextPtr; if (drvPtr->sock != INVALID_SOCKET) { ! drvPtr->nextPtr = activeDrvPtr; ! activeDrvPtr = drvPtr; } else { ! drvPtr->nextPtr = firstDrvPtr; ! firstDrvPtr = drvPtr; } drvPtr = nextDrvPtr; --- 722,728 ---- nextDrvPtr = drvPtr->nextPtr; if (drvPtr->sock != INVALID_SOCKET) { ! Push(drvPtr, activeDrvPtr); } else { ! Push(drvPtr, firstDrvPtr); } drvPtr = nextDrvPtr; *************** *** 826,831 **** SockRelease(sockPtr, Reason_CloseTimeout); } else { ! sockPtr->nextPtr = closePtr; ! closePtr = sockPtr; } sockPtr = nextPtr; --- 825,829 ---- SockRelease(sockPtr, Reason_CloseTimeout); } else { ! Push(sockPtr, closePtr); } sockPtr = nextPtr; *************** *** 845,850 **** SockRelease(sockPtr, Reason_ReadTimeout); } else { ! sockPtr->nextPtr = readPtr; ! readPtr = sockPtr; } } else { --- 843,847 ---- SockRelease(sockPtr, Reason_ReadTimeout); } else { ! Push(sockPtr, readPtr); } } else { *************** *** 868,873 **** case SOCK_MORE: SockTimeout(sockPtr, &now, sockPtr->drvPtr->recvwait); ! sockPtr->nextPtr = readPtr; ! readPtr = sockPtr; break; case SOCK_READY: --- 865,869 ---- case SOCK_MORE: SockTimeout(sockPtr, &now, sockPtr->drvPtr->recvwait); ! Push(sockPtr, readPtr); break; case SOCK_READY: *************** *** 875,880 **** SockRelease(sockPtr, Reason_ServerReject); } else { ! sockPtr->nextPtr = waitPtr; ! waitPtr = sockPtr; } break; --- 871,875 ---- SockRelease(sockPtr, Reason_ServerReject); } else { ! Push(sockPtr, waitPtr); } break; *************** *** 903,908 **** nextPtr = sockPtr->nextPtr; if (waitPtr != NULL || !NsQueueConn(sockPtr, &now)) { ! sockPtr->nextPtr = waitPtr; ! waitPtr = sockPtr; } sockPtr = nextPtr; --- 898,902 ---- nextPtr = sockPtr->nextPtr; if (waitPtr != NULL || !NsQueueConn(sockPtr, &now)) { ! Push(sockPtr, waitPtr); } sockPtr = nextPtr; *************** *** 926,932 **** * Add this driver to the temporary idle list. */ ! ! drvPtr->nextPtr = idleDrvPtr; ! idleDrvPtr = drvPtr; } else { --- 920,925 ---- * Add this driver to the temporary idle list. */ ! ! Push(drvPtr, idleDrvPtr); } else { *************** *** 935,941 **** * Add this driver to the temporary accepted list. */ ! ! drvPtr->nextPtr = acceptDrvPtr; ! acceptDrvPtr = drvPtr; /* --- 928,933 ---- * Add this driver to the temporary accepted list. */ ! ! Push(drvPtr, acceptDrvPtr); /* *************** *** 948,953 **** } else { if (!NsQueueConn(sockPtr, &now)) { ! sockPtr->nextPtr = waitPtr; ! waitPtr = sockPtr; } } --- 940,944 ---- } else { if (!NsQueueConn(sockPtr, &now)) { ! Push(sockPtr, waitPtr); } } *************** *** 958,963 **** SockTimeout(sockPtr, &now, sockPtr->drvPtr->recvwait); ! sockPtr->nextPtr = readPtr; ! readPtr = sockPtr; } } --- 949,953 ---- SockTimeout(sockPtr, &now, sockPtr->drvPtr->recvwait); ! Push(sockPtr, readPtr); } } *************** *** 973,983 **** while ((drvPtr = acceptDrvPtr) != NULL) { acceptDrvPtr = drvPtr->nextPtr; ! drvPtr->nextPtr = activeDrvPtr; ! activeDrvPtr = drvPtr; } while ((drvPtr = idleDrvPtr) != NULL) { idleDrvPtr = drvPtr->nextPtr; ! drvPtr->nextPtr = activeDrvPtr; ! activeDrvPtr = drvPtr; } } --- 963,971 ---- while ((drvPtr = acceptDrvPtr) != NULL) { acceptDrvPtr = drvPtr->nextPtr; ! Push(drvPtr, activeDrvPtr); } while ((drvPtr = idleDrvPtr) != NULL) { idleDrvPtr = drvPtr->nextPtr; ! Push(drvPtr, activeDrvPtr); } } *************** *** 1004,1009 **** if (sockPtr->keep) { SockTimeout(sockPtr, &now, sockPtr->drvPtr->keepwait); ! sockPtr->nextPtr = readPtr; ! readPtr = sockPtr; } else { if (shutdown(sockPtr->sock, 1) != 0) { --- 992,996 ---- if (sockPtr->keep) { SockTimeout(sockPtr, &now, sockPtr->drvPtr->keepwait); ! Push(sockPtr, readPtr); } else { if (shutdown(sockPtr->sock, 1) != 0) { *************** *** 1011,1016 **** } else { SockTimeout(sockPtr, &now, sockPtr->drvPtr->closewait); ! sockPtr->nextPtr = closePtr; ! closePtr = sockPtr; } } --- 998,1002 ---- } else { SockTimeout(sockPtr, &now, sockPtr->drvPtr->closewait); ! Push(sockPtr, closePtr); } } *************** *** 1029,1034 **** drvPtr->sock = INVALID_SOCKET; } ! drvPtr->nextPtr = firstDrvPtr; ! firstDrvPtr = drvPtr; } } --- 1015,1019 ---- drvPtr->sock = INVALID_SOCKET; } ! Push(drvPtr, firstDrvPtr); } } |
From: Stephen D. <sd...@us...> - 2006-01-07 22:26:39
|
Update of /cvsroot/naviserver/naviserver In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29551 Modified Files: ChangeLog Log Message: * nsd/driver.c (DriverThread): Add Push() macro to clarify list processing of sockets and drivers. Index: ChangeLog =================================================================== RCS file: /cvsroot/naviserver/naviserver/ChangeLog,v retrieving revision 1.266 retrieving revision 1.267 diff -C2 -d -r1.266 -r1.267 *** ChangeLog 6 Jan 2006 09:30:50 -0000 1.266 --- ChangeLog 7 Jan 2006 22:26:31 -0000 1.267 *************** *** 1,2 **** --- 1,7 ---- + 2006-01-07 Stephen Deasey <sd...@us...> + + * nsd/driver.c (DriverThread): Add Push() macro to clarify list + processing of sockets and drivers. + 2006-01-06 Zoran Vasiljevic <vas...@us...> |
From: Zoran V. <vas...@us...> - 2006-01-06 09:30:58
|
Update of /cvsroot/naviserver/naviserver In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15336 Modified Files: ChangeLog Log Message: See file Index: ChangeLog =================================================================== RCS file: /cvsroot/naviserver/naviserver/ChangeLog,v retrieving revision 1.265 retrieving revision 1.266 diff -C2 -d -r1.265 -r1.266 *** ChangeLog 4 Jan 2006 14:08:50 -0000 1.265 --- ChangeLog 6 Jan 2006 09:30:50 -0000 1.266 *************** *** 1,2 **** --- 1,7 ---- + 2006-01-06 Zoran Vasiljevic <vas...@us...> + + * tests/ns_conn.test: fixed basic command test to recognize + new "contentsentlength" command option. + 2006-01-04 Zoran Vasiljevic <vas...@us...> |
From: Zoran V. <vas...@us...> - 2006-01-06 09:29:16
|
Update of /cvsroot/naviserver/naviserver/tests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14991/tests Modified Files: ns_conn.test Log Message: Fixed ns_conn.test to recognize new contentsentlenght option during basic command test Index: ns_conn.test =================================================================== RCS file: /cvsroot/naviserver/naviserver/tests/ns_conn.test,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** ns_conn.test 20 Oct 2005 17:02:45 -0000 1.1 --- ns_conn.test 6 Jan 2006 09:29:07 -0000 1.2 *************** *** 14,18 **** test ns_conn-1.2 {basic syntax: wrong argument} -body { ns_conn 123 ! } -returnCodes error -result {bad option "123": must be authpassword, authuser, close, content, contentlength, copy, channel, driver, encoding, files, fileoffset, filelength, fileheaders, flags, form, headers, host, id, isconnected, location, method, outputheaders, peeraddr, peerport, port, protocol, query, request, server, sock, start, status, url, urlc, urlencoding, urlv, version, write_encoded, chunked, or responseversion} test ns_conn-2.1 {basic operation} -body { --- 14,18 ---- test ns_conn-1.2 {basic syntax: wrong argument} -body { ns_conn 123 ! } -returnCodes error -result {bad option "123": must be authpassword, authuser, close, content, contentlength, contentsentlength, copy, channel, driver, encoding, files, fileoffset, filelength, fileheaders, flags, form, headers, host, id, isconnected, location, method, outputheaders, peeraddr, peerport, port, protocol, query, request, server, sock, start, status, url, urlc, urlencoding, urlv, version, write_encoded, chunked, or responseversion} test ns_conn-2.1 {basic operation} -body { |
From: Vlad S. <ser...@us...> - 2006-01-05 15:36:46
|
Update of /cvsroot/naviserver/modules/nssnmp In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13728 Modified Files: ChangeLog nssnmp.c Log Message: added debug config option Index: nssnmp.c =================================================================== RCS file: /cvsroot/naviserver/modules/nssnmp/nssnmp.c,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** nssnmp.c 21 Nov 2005 18:18:14 -0000 1.9 --- nssnmp.c 5 Jan 2006 15:36:33 -0000 1.10 *************** *** 379,382 **** --- 379,383 ---- char *community; char *writecommunity; + int debug; int port; int bulk; *************** *** 513,516 **** --- 514,518 ---- serverPtr->name = server; Tcl_InitHashTable(&serverPtr->mib,TCL_STRING_KEYS); + if(!Ns_ConfigGetInt(path,"debug",&serverPtr->debug)) serverPtr->debug = 0; if(!Ns_ConfigGetInt(path,"idle_timeout",&serverPtr->idle_timeout)) serverPtr->idle_timeout = 600; if(!Ns_ConfigGetInt(path,"gc_interval",&serverPtr->gc_interval)) serverPtr->gc_interval = 600; *************** *** 652,656 **** TrapContext *ctx = new TrapContext(server); if(!receive_snmp_notification(sock,*server->trap.snmp,ctx->pdu,&ctx->target)) { ! TrapDump(server,ctx->pdu,*ctx->target); /* SNMP inform trap requires response */ if (ctx->pdu.get_type() == sNMP_PDU_INFORM) { --- 654,660 ---- TrapContext *ctx = new TrapContext(server); if(!receive_snmp_notification(sock,*server->trap.snmp,ctx->pdu,&ctx->target)) { ! if (server->debug) { ! TrapDump(server,ctx->pdu,*ctx->target); ! } /* SNMP inform trap requires response */ if (ctx->pdu.get_type() == sNMP_PDU_INFORM) { *************** *** 2012,2015 **** --- 2016,2022 ---- * * $Log$ + * Revision 1.10 2006/01/05 15:36:33 seryakov + * added debug config option + * * Revision 1.9 2005/11/21 18:18:14 seryakov * *** empty log message *** Index: ChangeLog =================================================================== RCS file: /cvsroot/naviserver/modules/nssnmp/ChangeLog,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** ChangeLog 21 Nov 2005 18:18:14 -0000 1.5 --- ChangeLog 5 Jan 2006 15:36:33 -0000 1.6 *************** *** 1,2 **** --- 1,6 ---- + 2006-01-05 Vlad Seryakov vl...@cr... + + * added debug option to snmp traps + 2005-11-21 Vlad Seryakov vl...@cr... |
From: Zoran V. <vas...@us...> - 2006-01-04 14:09:03
|
Update of /cvsroot/naviserver/naviserver In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16117 Modified Files: ChangeLog Log Message: See file. Index: ChangeLog =================================================================== RCS file: /cvsroot/naviserver/naviserver/ChangeLog,v retrieving revision 1.264 retrieving revision 1.265 diff -C2 -d -r1.264 -r1.265 *** ChangeLog 4 Jan 2006 10:15:52 -0000 1.264 --- ChangeLog 4 Jan 2006 14:08:50 -0000 1.265 *************** *** 1,2 **** --- 1,12 ---- + 2006-01-04 Zoran Vasiljevic <vas...@us...> + + * configure.in: added test for inet_ntop. + * nsthread/reentrant.c: use inet_ntop when available which fixes a + bug on 64 bit ppc, at least under linux. + * nsd/conn.c: added option to [ns_conn] to set/query contentsentlength + for getting the correct length into the logfile, when files are + delivered via event driven I/O. Thanks to Gustaf Neumann for providing + above fixes. + 2006-01-04 Stephen Deasey <sd...@us...> |
From: Zoran V. <vas...@us...> - 2006-01-04 14:08:25
|
Update of /cvsroot/naviserver/naviserver/nsd In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15762/nsd Modified Files: conn.c Log Message: * configure.in: added test for inet_ntop. * nsthread/reentrant.c: use inet_ntop when available which fixes a bug on 64 bit ppc, at least under linux. * nsd/conn.c: added option to [ns_conn] to set/query contentsentlength for getting the correct length into the logfile, when files are delivered via event driven I/O. Thanks to Gustaf Neumann for providing above fixes. Index: conn.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/conn.c,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** conn.c 12 Nov 2005 20:50:33 -0000 1.23 --- conn.c 4 Jan 2006 14:08:03 -0000 1.24 *************** *** 1031,1034 **** --- 1031,1035 ---- static CONST char *opts[] = { "authpassword", "authuser", "close", "content", "contentlength", + "contentsentlength", "copy", "channel", "driver", "encoding", "files", "fileoffset", "filelength", "fileheaders", "flags", "form", "headers", *************** *** 1042,1046 **** enum ISubCmdIdx { CAuthPasswordIdx, CAuthUserIdx, CCloseIdx, CContentIdx, ! CContentLengthIdx, CCopyIdx, CChannelIdx, CDriverIdx, CEncodingIdx, CFilesIdx, CFileOffIdx, CFileLenIdx, CFileHdrIdx, CFlagsIdx, CFormIdx, CHeadersIdx, CHostIdx, CIdIdx, CIsConnectedIdx, --- 1043,1047 ---- enum ISubCmdIdx { CAuthPasswordIdx, CAuthUserIdx, CCloseIdx, CContentIdx, ! CContentLengthIdx, CContentSentLenIdx, CCopyIdx, CChannelIdx, CDriverIdx, CEncodingIdx, CFilesIdx, CFileOffIdx, CFileLenIdx, CFileHdrIdx, CFlagsIdx, CFormIdx, CHeadersIdx, CHostIdx, CIdIdx, CIsConnectedIdx, *************** *** 1397,1400 **** --- 1398,1415 ---- Tcl_RegisterChannel(interp, chan); Tcl_SetStringObj(result, Tcl_GetChannelName(chan), -1); + break; + + case CContentSentLenIdx: + if (objc == 2) { + Tcl_SetIntObj(result, connPtr->nContentSent); + } else if (objc == 3) { + if (Tcl_GetIntFromObj(interp, objv[2], &connPtr->nContentSent) != TCL_OK) { + return TCL_ERROR; + } + } else { + Tcl_WrongNumArgs(interp, 2, objv, "?value?"); + return TCL_ERROR; + } + break; } |
From: Zoran V. <vas...@us...> - 2006-01-04 14:08:25
|
Update of /cvsroot/naviserver/naviserver/nsthread In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15762/nsthread Modified Files: reentrant.c Log Message: * configure.in: added test for inet_ntop. * nsthread/reentrant.c: use inet_ntop when available which fixes a bug on 64 bit ppc, at least under linux. * nsd/conn.c: added option to [ns_conn] to set/query contentsentlength for getting the correct length into the logfile, when files are delivered via event driven I/O. Thanks to Gustaf Neumann for providing above fixes. Index: reentrant.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsthread/reentrant.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** reentrant.c 10 Jun 2005 17:58:59 -0000 1.2 --- reentrant.c 4 Jan 2006 14:08:03 -0000 1.3 *************** *** 73,76 **** --- 73,79 ---- { Tls *tlsPtr = GetTls(); + #if defined(HAVE_INET_NTOP) + inet_ntop(AF_INET, &addr, tlsPtr->nabuf, sizeof(tlsPtr->nabuf)); + #else union { unsigned long l; *************** *** 80,83 **** --- 83,87 ---- u.l = (unsigned long) addr.s_addr; sprintf(tlsPtr->nabuf, "%u.%u.%u.%u", u.b[0], u.b[1], u.b[2], u.b[3]); + #endif return tlsPtr->nabuf; } |
From: Zoran V. <vas...@us...> - 2006-01-04 14:08:23
|
Update of /cvsroot/naviserver/naviserver In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15762 Modified Files: configure.in Log Message: * configure.in: added test for inet_ntop. * nsthread/reentrant.c: use inet_ntop when available which fixes a bug on 64 bit ppc, at least under linux. * nsd/conn.c: added option to [ns_conn] to set/query contentsentlength for getting the correct length into the logfile, when files are delivered via event driven I/O. Thanks to Gustaf Neumann for providing above fixes. Index: configure.in =================================================================== RCS file: /cvsroot/naviserver/naviserver/configure.in,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** configure.in 2 Nov 2005 23:07:15 -0000 1.18 --- configure.in 4 Jan 2006 14:08:02 -0000 1.19 *************** *** 253,256 **** --- 253,267 ---- AC_HAVE_CMMSG + dnl ** Check for inet_ntop + AC_MSG_CHECKING(for inet_ntop) + AC_TRY_COMPILE([#include <sys/socket.h> + #include <arpa/inet.h>], [inet_ntop(0, (char *)0, (char *)0, 0);], has_inet_ntop=yes, has_inet_ntop=no) + if test "$has_inet_ntop" = yes; then + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_INET_NTOP,,[we can use inet_ntop()]) + else + AC_MSG_RESULT(no) + fi + # # Create Makefiles. |
From: Stephen D. <sd...@us...> - 2006-01-04 10:16:05
|
Update of /cvsroot/naviserver/naviserver/include In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28689/include Modified Files: ns.h Log Message: * include/ns.h: * nsd/nsd.h: * nsd/Makefile: * nsd/nsmain.c: * nsd/sock.c: * nsd/task.c: Backport AOLserver task queues. Callbacks are registered to run in a seperate thread in response to socket read/write events. Index: ns.h =================================================================== RCS file: /cvsroot/naviserver/naviserver/include/ns.h,v retrieving revision 1.66 retrieving revision 1.67 diff -C2 -d -r1.66 -r1.67 *** ns.h 30 Dec 2005 11:26:42 -0000 1.66 --- ns.h 4 Jan 2006 10:15:52 -0000 1.67 *************** *** 136,140 **** #define NS_SOCK_DROP 0x10 /* Unused */ #define NS_SOCK_CANCEL 0x20 /* Remove event from sock callback thread */ ! #define NS_SOCK_ANY 0xFF /* ??? */ /* --- 136,142 ---- #define NS_SOCK_DROP 0x10 /* Unused */ #define NS_SOCK_CANCEL 0x20 /* Remove event from sock callback thread */ ! #define NS_SOCK_TIMEOUT 0x40 /* Timeout waiting for socket event. */ ! #define NS_SOCK_INIT 0x80 /* Initialise a Task callback. */ ! #define NS_SOCK_ANY (NS_SOCK_READ|NS_SOCK_WRITE|NS_SOCK_EXCEPTION) /* *************** *** 278,281 **** --- 280,294 ---- #define NS_DSTRING_PRINTF_MAX 2048 + /* + * Typedefs of variables + */ + + typedef struct _Ns_Cache *Ns_Cache; + typedef struct _Ns_Entry *Ns_Entry; + typedef Tcl_HashSearch Ns_CacheSearch; + typedef struct _Ns_Cls *Ns_Cls; + typedef void *Ns_OpContext; + typedef struct _Ns_TaskQueue *Ns_TaskQueue; + typedef struct _Ns_Task *Ns_Task; /* *************** *** 317,320 **** --- 330,334 ---- typedef void (Ns_TclDeferProc) (Tcl_Interp *interp, void *arg); typedef int (Ns_SockProc) (SOCKET sock, void *arg, int why); + typedef void (Ns_TaskProc) (Ns_Task *task, SOCKET sock, void *arg, int why); typedef void (Ns_SchedProc) (void *arg, int id); typedef int (Ns_ServerInitProc) (char *server); *************** *** 531,545 **** /* - * Typedefs of variables - */ - - typedef struct _Ns_Cache *Ns_Cache; - typedef struct _Ns_Entry *Ns_Entry; - typedef Tcl_HashSearch Ns_CacheSearch; - - typedef struct _Ns_Cls *Ns_Cls; - typedef void *Ns_OpContext; - - /* * adpparse.c: */ --- 545,548 ---- *************** *** 1087,1090 **** --- 1090,1137 ---- NS_EXTERN double Ns_DRand(void); + /* + * task.c: + */ + + NS_EXTERN Ns_TaskQueue * + Ns_CreateTaskQueue(char *name) + NS_GNUC_NONNULL(1); + + NS_EXTERN void + Ns_DestroyTaskQueue(Ns_TaskQueue *queue) + NS_GNUC_NONNULL(1); + + NS_EXTERN Ns_Task * + Ns_TaskCreate(SOCKET sock, Ns_TaskProc *proc, void *arg) + NS_GNUC_NONNULL(2); + + NS_EXTERN int + Ns_TaskEnqueue(Ns_Task *task, Ns_TaskQueue *queue) + NS_GNUC_NONNULL(1) NS_GNUC_NONNULL(2); + + NS_EXTERN void + Ns_TaskRun(Ns_Task *task) + NS_GNUC_NONNULL(1); + + NS_EXTERN void + Ns_TaskCallback(Ns_Task *task, int when, Ns_Time *timeoutPtr) + NS_GNUC_NONNULL(1); + + NS_EXTERN void + Ns_TaskDone(Ns_Task *task) + NS_GNUC_NONNULL(1); + + NS_EXTERN int + Ns_TaskCancel(Ns_Task *task) + NS_GNUC_NONNULL(1); + + NS_EXTERN int + Ns_TaskWait(Ns_Task *task, Ns_Time *timeoutPtr) + NS_GNUC_NONNULL(1); + + NS_EXTERN SOCKET + Ns_TaskFree(Ns_Task *task) + NS_GNUC_NONNULL(1); + /* * tclobj.c: |
From: Stephen D. <sd...@us...> - 2006-01-04 10:16:05
|
Update of /cvsroot/naviserver/naviserver/nsd In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28689/nsd Modified Files: Makefile nsd.h nsmain.c sock.c Added Files: task.c Log Message: * include/ns.h: * nsd/nsd.h: * nsd/Makefile: * nsd/nsmain.c: * nsd/sock.c: * nsd/task.c: Backport AOLserver task queues. Callbacks are registered to run in a seperate thread in response to socket read/write events. Index: nsd.h =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/nsd.h,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -d -r1.42 -r1.43 *** nsd.h 30 Dec 2005 11:07:34 -0000 1.42 --- nsd.h 4 Jan 2006 10:15:52 -0000 1.43 *************** *** 851,854 **** --- 851,855 ---- extern int NsSockSend(Sock *sockPtr, struct iovec *bufs, int nbufs); extern void NsSockClose(Sock *sockPtr, int keep); + extern int NsPoll(struct pollfd *pfds, int nfds, Ns_Time *timeoutPtr); extern Request *NsGetRequest(Sock *sockPtr); *************** *** 939,942 **** --- 940,945 ---- extern void NsStartShutdownProcs(void); extern void NsWaitShutdownProcs(Ns_Time *toPtr); + extern void NsStartTaskQueueShutdown(void); + extern void NsWaitTaskQueueShutdown(Ns_Time *toPtr); extern void NsStartJobsShutdown(void); Index: Makefile =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/Makefile,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** Makefile 30 Dec 2005 11:07:34 -0000 1.8 --- Makefile 4 Jan 2006 10:15:52 -0000 1.9 *************** *** 46,54 **** quotehtml.o random.o request.o return.o rollfile.o sched.o \ server.o set.o sock.o sockcallback.o str.o \ ! tclcache.o tclcallbacks.o tclcmds.o tclconf.o tclenv.o tclfile.o tclhttp.o tclimg.o \ ! tclinit.o tcljob.o tclmisc.o tclobj.o tclobjv.o tclrequest.o tclresp.o \ ! tclsched.o tclset.o tclshare.o tclsock.o tclthread.o tcltime.o tclvar.o \ ! tclxkeylist.o unix.o url.o url2file.o urlencode.o urlopen.o urlspace.o \ ! uuencode.o LIBOBJS = $(LOBJS) stamp.o --- 46,54 ---- quotehtml.o random.o request.o return.o rollfile.o sched.o \ server.o set.o sock.o sockcallback.o str.o \ ! task.o tclcache.o tclcallbacks.o tclcmds.o tclconf.o tclenv.o tclfile.o \ ! tclhttp.o tclimg.o tclinit.o tcljob.o tclmisc.o tclobj.o tclobjv.o \ ! tclrequest.o tclresp.o tclsched.o tclset.o tclshare.o tclsock.o \ ! tclthread.o tcltime.o tclvar.o tclxkeylist.o \ ! unix.o url.o url2file.o urlencode.o urlopen.o urlspace.o uuencode.o LIBOBJS = $(LOBJS) stamp.o Index: nsmain.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/nsmain.c,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -d -r1.31 -r1.32 *** nsmain.c 24 Nov 2005 19:36:10 -0000 1.31 --- nsmain.c 4 Jan 2006 10:15:52 -0000 1.32 *************** *** 792,803 **** */ - NsWaitDriversShutdown(&timeout); NsStartSchedShutdown(); NsStartSockShutdown(); NsStartJobsShutdown(); NsStartShutdownProcs(); NsWaitSchedShutdown(&timeout); NsWaitSockShutdown(&timeout); NsWaitJobsShutdown(&timeout); NsWaitShutdownProcs(&timeout); --- 792,806 ---- */ NsStartSchedShutdown(); NsStartSockShutdown(); + NsStartTaskQueueShutdown(); NsStartJobsShutdown(); NsStartShutdownProcs(); + NsWaitSchedShutdown(&timeout); NsWaitSockShutdown(&timeout); + NsWaitTaskQueueShutdown(&timeout); NsWaitJobsShutdown(&timeout); + NsWaitDriversShutdown(&timeout); NsWaitShutdownProcs(&timeout); --- NEW FILE: task.c --- /* * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://mozilla.org/. * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is AOLserver Code and related documentation * distributed by AOL. * * The Initial Developer of the Original Code is America Online, * Inc. Portions created by AOL are Copyright (C) 1999 America Online, * Inc. All Rights Reserved. * * Alternatively, the contents of this file may be used under the terms * of the GNU General Public License (the "GPL"), in which case the * provisions of GPL are applicable instead of those above. If you wish * to allow use of your version of this file only under the terms of the * GPL and not to allow others to use your version of this file under the * License, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the GPL. * If you do not delete the provisions above, a recipient may use your * version of this file under either the License or the GPL. */ /* * task.c -- * * Support socket for I/O tasks. */ #include "nsd.h" NS_RCSID("@(#) $Header: /cvsroot/naviserver/naviserver/nsd/task.c,v 1.1 2006/01/04 10:15:52 sdeasey Exp $"); /* * The following defines a task queue. */ #define NAME_SIZE 31 typedef struct TaskQueue { struct TaskQueue *nextPtr; /* Next in list of all queues. */ struct Task *firstSignalPtr; /* First in list of task signals. */ Ns_Thread tid; /* Thread id. */ Ns_Mutex lock; /* Queue list and signal lock. */ Ns_Cond cond; /* Task and queue signal condition. */ int shutdown; /* Shutdown flag. */ int stopped; /* Stop flag. */ SOCKET trigger[2]; /* Trigger pipe. */ char name[NAME_SIZE+1]; /* String name. */ } TaskQueue; /* * The following bits are used to send signals to a task queue * and manage the state tasks. */ #define TASK_INIT 0x01 #define TASK_CANCEL 0x02 #define TASK_WAIT 0x04 #define TASK_TIMEOUT 0x08 #define TASK_DONE 0x10 #define TASK_PENDING 0x20 /* * The following defines a task. */ typedef struct Task { struct TaskQueue *queuePtr; /* Monitoring queue. */ struct Task *nextWaitPtr; /* Next on wait queue. */ struct Task *nextSignalPtr; /* Next on signal queue. */ SOCKET sock; /* Underlying socket. */ Ns_TaskProc *proc; /* Queue callback. */ void *arg; /* Callback data. */ int idx; /* Poll index. */ int events; /* Poll events. */ Ns_Time timeout; /* Non-null timeout data. */ int signal; /* Signal bits sent to/from queue thread. */ int flags; /* Flags private to queue. */ } Task; /* * Local functions defined in this file */ static void TriggerQueue(TaskQueue *queuePtr); static void JoinQueue(TaskQueue *queuePtr); static void StopQueue(TaskQueue *queuePtr); static int SignalQueue(Task *taskPtr, int bit); static Ns_ThreadProc TaskThread; static void RunTask(Task *taskPtr, int revents, Ns_Time *nowPtr); #define Call(tp,w) ((*((tp)->proc))((Ns_Task *)(tp),(tp)->sock,(tp)->arg,(w))) /* * Static variables defined in this file */ static TaskQueue *firstQueuePtr; /* List of all queues. */ static Ns_Mutex lock; /* Lock for queue list. */ /* * The following maps sock "when" bits to poll event bits. * The order is significant and determines the order of callbacks * when multiple events are ready. */ static struct { int when; /* SOCK when bit. */ int event; /* Poll event bit. */ } map[] = { {NS_SOCK_EXCEPTION, POLLPRI}, {NS_SOCK_WRITE, POLLOUT}, {NS_SOCK_READ, POLLIN} }; /* *---------------------------------------------------------------------- * * Ns_CreateTaskQueue -- * * Create a new task queue. * * Results: * Handle to task queue. * * Side effects: * None. * *---------------------------------------------------------------------- */ Ns_TaskQueue * Ns_CreateTaskQueue(char *name) { TaskQueue *queuePtr; queuePtr = ns_calloc(1, sizeof(TaskQueue)); strncpy(queuePtr->name, name ? name : "", NAME_SIZE); if (ns_sockpair(queuePtr->trigger) != 0) { Ns_Fatal("taskqueue: ns_sockpair() failed: %s", ns_sockstrerror(ns_sockerrno)); } Ns_MutexLock(&lock); queuePtr->nextPtr = firstQueuePtr; firstQueuePtr = queuePtr; Ns_ThreadCreate(TaskThread, queuePtr, 0, &queuePtr->tid); Ns_MutexUnlock(&lock); return (Ns_TaskQueue *) queuePtr; } /* *---------------------------------------------------------------------- * * Ns_DestoryTaskQueue -- * * Stop and join a task queue. * * Results: * None. * * Side effects: * Pending tasks callbacks, if any, are cancelled. * *---------------------------------------------------------------------- */ void Ns_DestroyTaskQueue(Ns_TaskQueue *queue) { TaskQueue *queuePtr = (TaskQueue *) queue; TaskQueue **nextPtrPtr; /* * Remove queue from list of all queues. */ Ns_MutexLock(&lock); nextPtrPtr = &firstQueuePtr; while (*nextPtrPtr != queuePtr) { nextPtrPtr = &(*nextPtrPtr)->nextPtr; } *nextPtrPtr = queuePtr->nextPtr; Ns_MutexUnlock(&lock); /* * Signal stop and wait for join. */ StopQueue(queuePtr); JoinQueue(queuePtr); } /* *---------------------------------------------------------------------- * * Ns_TaskCreate -- * * Create a new task. * * Results: * Handle to task. * * Side effects: * None. * *---------------------------------------------------------------------- */ Ns_Task * Ns_TaskCreate(SOCKET sock, Ns_TaskProc *proc, void *arg) { Task *taskPtr; taskPtr = ns_calloc(1, sizeof(Task)); taskPtr->sock = sock; taskPtr->proc = proc; taskPtr->arg = arg; return (Ns_Task *) taskPtr; } /* *---------------------------------------------------------------------- * * Ns_TaskEnqueue -- * * Add a task to a queue. * * Results: * NS_OK if task sent, NS_ERROR otherwise. * * Side effects: * Queue will begin running the task. * *---------------------------------------------------------------------- */ int Ns_TaskEnqueue(Ns_Task *task, Ns_TaskQueue *queue) { Task *taskPtr = (Task *) task; TaskQueue *queuePtr = (TaskQueue *) queue; taskPtr->queuePtr = queuePtr; if (!SignalQueue(taskPtr, TASK_INIT)) { return NS_ERROR; } return NS_OK; } /* *---------------------------------------------------------------------- * * Ns_TaskRun -- * * Run a task directly, waiting for completion. * * Results: * None. * * Side effects: * Depends on task callback. * *---------------------------------------------------------------------- */ void Ns_TaskRun(Ns_Task *task) { Task *taskPtr = (Task *) task; Ns_Time now, *timeoutPtr; struct pollfd pfd; pfd.fd = taskPtr->sock; Call(taskPtr, NS_SOCK_INIT); while (!(taskPtr->flags & TASK_DONE)) { if (taskPtr->flags & TASK_TIMEOUT) { timeoutPtr = &taskPtr->timeout; } else { timeoutPtr = NULL; } pfd.revents = 0; pfd.events = taskPtr->events; if (NsPoll(&pfd, 1, timeoutPtr) != 1) { break; } Ns_GetTime(&now); RunTask(taskPtr, pfd.revents, &now); } taskPtr->signal |= TASK_DONE; } /* *---------------------------------------------------------------------- * * Ns_TaskCancel -- * * Signal a task queue to stop running a task. * * Results: * NS_OK if cancel sent, NS_ERROR otherwise. * * Side effects: * Task callback will be invoke with NS_SOCK_CANCEL and is * expected to call Ns_TaskDone to indicate completion. * *---------------------------------------------------------------------- */ int Ns_TaskCancel(Ns_Task *task) { Task *taskPtr = (Task *) task; if (taskPtr->queuePtr == NULL) { taskPtr->signal |= TASK_CANCEL; } else if (!SignalQueue(taskPtr, TASK_CANCEL)) { return NS_ERROR; } return NS_OK; } /* *---------------------------------------------------------------------- * * Ns_TaskWait -- * * Wait for a task to complete. Infinite wait is indicated * by a NULL timeoutPtr. * * Results: * NS_TIMEOUT if task did not complete by absolute time, * NS_OK otherwise. * * Side effects: * May wait up to specified timeout. * *---------------------------------------------------------------------- */ int Ns_TaskWait(Ns_Task *task, Ns_Time *timeoutPtr) { Task *taskPtr = (Task *) task; TaskQueue *queuePtr = taskPtr->queuePtr; int status = NS_OK; if (queuePtr == NULL) { if (!(taskPtr->signal & TASK_DONE)) { status = NS_TIMEOUT; } } else { Ns_MutexLock(&queuePtr->lock); while (status == NS_OK && !(taskPtr->signal & TASK_DONE)) { status = Ns_CondTimedWait(&queuePtr->cond, &queuePtr->lock, timeoutPtr); } Ns_MutexUnlock(&queuePtr->lock); if (status == NS_OK) { taskPtr->queuePtr = NULL; } } return status; } /* *---------------------------------------------------------------------- * * Ns_TaskCallback -- * * Update pending conditions and timeout for a task. This * routine is expected to be called from within the task * callback proc including to set the initial wait conditions * from within the NS_SOCK_INIT callback. * * Results: * None. * * Side effects: * Task callback will be invoked when ready or on timeout. * *---------------------------------------------------------------------- */ void Ns_TaskCallback(Ns_Task *task, int when, Ns_Time *timeoutPtr) { Task *taskPtr = (Task *) task; int i; /* * Map from sock when bits to poll event bits. */ taskPtr->events = 0; for (i = 0; i < 3; ++i) { if (when & map[i].when) { taskPtr->events |= map[i].event; } } /* * Copy timeout, if any. */ if (timeoutPtr == NULL) { taskPtr->flags &= ~TASK_TIMEOUT; } else { taskPtr->flags |= TASK_TIMEOUT; taskPtr->timeout = *timeoutPtr; } /* * Mark as waiting if there are events or a timeout. */ if (taskPtr->events || timeoutPtr) { taskPtr->flags |= TASK_WAIT; } else { taskPtr->flags &= ~TASK_WAIT; } } /* *---------------------------------------------------------------------- * * Ns_TaskDone -- * * Mark a task as done. This routine should be called from * within the task callback. The task queue thread will signal * other waiting threads, if any, on next spin. * * Results: * None. * * Side effects: * Task queue will signal this task is done on next spin. * *---------------------------------------------------------------------- */ void Ns_TaskDone(Ns_Task *event) { Task *taskPtr = (Task *) event; taskPtr->flags |= TASK_DONE; } /* *---------------------------------------------------------------------- * * Ns_TaskFree -- * * Free task structure. The caller is responsible for * ensuring the task is no longer being run or monitored * a task queue. * * Results: * The task SOCKET which the caller is responsible for closing * or reusing. * * Side effects: * None. * *---------------------------------------------------------------------- */ SOCKET Ns_TaskFree(Ns_Task *task) { Task *taskPtr = (Task *) task; SOCKET sock = taskPtr->sock; ns_free(taskPtr); return sock; } /* *---------------------------------------------------------------------- * * NsStartTaskQueueShutdown -- * * Trigger all task queues to begin shutdown. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void NsStartTaskQueueShutdown(void) { TaskQueue *queuePtr; /* * Trigger all queues to shutdown. */ Ns_MutexLock(&lock); queuePtr = firstQueuePtr; while (queuePtr != NULL) { StopQueue(queuePtr); queuePtr = queuePtr->nextPtr; } Ns_MutexUnlock(&lock); } /* *---------------------------------------------------------------------- * * NsWaitTaskQueueShutdown -- * * Wait for all task queues to shutdown. * * Results: * None. * * Side effects: * May timeout waiting for shutdown. * *---------------------------------------------------------------------- */ void NsWaitTaskQueueShutdown(Ns_Time *toPtr) { TaskQueue *queuePtr, *nextPtr; int status; /* * Clear out list of any remaining task queues. */ Ns_MutexLock(&lock); queuePtr = firstQueuePtr; firstQueuePtr = NULL; Ns_MutexUnlock(&lock); /* * Join all queues possible within total allowed time. */ status = NS_OK; while (status == NS_OK && queuePtr != NULL) { nextPtr = queuePtr->nextPtr; Ns_MutexLock(&queuePtr->lock); while (status == NS_OK && !queuePtr->stopped) { status = Ns_CondTimedWait(&queuePtr->cond, &queuePtr->lock, toPtr); } Ns_MutexUnlock(&queuePtr->lock); if (status == NS_OK) { JoinQueue(queuePtr); } queuePtr = nextPtr; } if (status != NS_OK) { Ns_Log(Warning, "timeout waiting for task queue shutdown"); } } /* *---------------------------------------------------------------------- * * RunTask -- * * Run a single task from either a task queue or a directly via * Ns_TaskRun. * * Results: * None. * * Side effects: * Depends on callbacks of given task. * *---------------------------------------------------------------------- */ static void RunTask(Task *taskPtr, int revents, Ns_Time *nowPtr) { int i; /* * NB: Treat POLLHUP as POLLIN on systems which return it. */ if (revents & POLLHUP) { revents |= POLLIN; } if (revents) { for (i = 0; i < 3; ++i) { if (revents & map[i].event) { Call(taskPtr, map[i].when); } } } else if ((taskPtr->flags & TASK_TIMEOUT) && Ns_DiffTime(&taskPtr->timeout, nowPtr, NULL) < 0) { taskPtr->flags &= ~ TASK_WAIT; Call(taskPtr, NS_SOCK_TIMEOUT); } } /* *---------------------------------------------------------------------- * * SignalQueue -- * * Send a signal for a task to a task queue. * * Results: * None. * * Side effects: * Task queue will process signal on next spin. * *---------------------------------------------------------------------- */ static int SignalQueue(Task *taskPtr, int bit) { TaskQueue *queuePtr = taskPtr->queuePtr; int pending = 0, shutdown; Ns_MutexLock(&queuePtr->lock); shutdown = queuePtr->shutdown; if (!shutdown) { /* * Mark the signal and add event to signal list if not * already there. */ taskPtr->signal |= bit; pending = (taskPtr->signal & TASK_PENDING); if (!pending) { taskPtr->signal |= TASK_PENDING; taskPtr->nextSignalPtr = queuePtr->firstSignalPtr; queuePtr->firstSignalPtr = taskPtr; } } Ns_MutexUnlock(&queuePtr->lock); if (shutdown) { return 0; } if (!pending) { TriggerQueue(queuePtr); } return 1; } /* *---------------------------------------------------------------------- * * TriggerQueue -- * * Wakeup a task queue. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ static void TriggerQueue(TaskQueue *queuePtr) { if (send(queuePtr->trigger[1], "", 1, 0) != 1) { Ns_Fatal("task queue: trigger send() failed: %s", ns_sockstrerror(ns_sockerrno)); } } /* *---------------------------------------------------------------------- * * StopQueue -- * * Signal a task queue to shutdown. * * Results: * None. * * Side effects: * Queue will exit on next spin and call remaining tasks * with NS_SOCK_EXIT. * *---------------------------------------------------------------------- */ static void StopQueue(TaskQueue *queuePtr) { Ns_MutexLock(&queuePtr->lock); queuePtr->shutdown = 1; Ns_MutexUnlock(&queuePtr->lock); TriggerQueue(queuePtr); } /* *---------------------------------------------------------------------- * * JoinQueue -- * * Cleanup resources of a task queue. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ static void JoinQueue(TaskQueue *queuePtr) { Ns_ThreadJoin(&queuePtr->tid, NULL); ns_sockclose(queuePtr->trigger[0]); ns_sockclose(queuePtr->trigger[1]); Ns_MutexDestroy(&queuePtr->lock); ns_free(queuePtr); } /* *---------------------------------------------------------------------- * * TaskThread -- * * Run a task queue. * * Results: * None. * * Side effects: * Depends on callbacks of given tasks. * *---------------------------------------------------------------------- */ static void TaskThread(void *arg) { TaskQueue *queuePtr = arg; char c; int n, broadcast, max, nfds, shutdown; Task *taskPtr, *nextPtr, *firstWaitPtr; struct pollfd *pfds; Ns_Time now, *timeoutPtr; char name[NAME_SIZE+10]; sprintf(name, "task:%s", queuePtr->name); Ns_ThreadSetName(name); Ns_Log(Notice, "starting"); max = 100; pfds = ns_malloc(sizeof(struct pollfd) * max); firstWaitPtr = NULL; while (1) { /* * Get the shutdown flag and process any incoming signals. */ Ns_MutexLock(&queuePtr->lock); shutdown = queuePtr->shutdown; while ((taskPtr = queuePtr->firstSignalPtr) != NULL) { queuePtr->firstSignalPtr = taskPtr->nextSignalPtr; taskPtr->nextSignalPtr = NULL; if (!(taskPtr->flags & TASK_WAIT)) { taskPtr->flags |= TASK_WAIT; taskPtr->nextWaitPtr = firstWaitPtr; firstWaitPtr = taskPtr; } if (taskPtr->signal & TASK_INIT) { taskPtr->signal &= ~TASK_INIT; taskPtr->flags |= TASK_INIT; } if (taskPtr->signal & TASK_CANCEL) { taskPtr->signal &= ~TASK_CANCEL; taskPtr->flags |= TASK_CANCEL; } taskPtr->signal &= ~TASK_PENDING; } Ns_MutexUnlock(&queuePtr->lock); /* * Invoke pre-poll callbacks, determine minimum timeout, and set * the pollfd structs for all waiting tasks. */ pfds[0].fd = queuePtr->trigger[0]; pfds[0].events = POLLIN; pfds[0].revents = 0; nfds = 1; timeoutPtr = NULL; taskPtr = firstWaitPtr; firstWaitPtr = NULL; broadcast = 0; while (taskPtr != NULL) { nextPtr = taskPtr->nextWaitPtr; /* * Call init and/or cancel and signal done if necessary. * Note that a task can go from init to done immediately * so all required callbacks are invoked before determining * if a wait is required. */ if (taskPtr->flags & TASK_INIT) { taskPtr->flags &= ~TASK_INIT; Call(taskPtr, NS_SOCK_INIT); } if (taskPtr->flags & TASK_CANCEL) { taskPtr->flags &= ~(TASK_CANCEL|TASK_WAIT); taskPtr->flags |= TASK_DONE; Call(taskPtr, NS_SOCK_CANCEL); } if (taskPtr->flags & TASK_DONE) { taskPtr->flags &= ~(TASK_DONE|TASK_WAIT); Ns_MutexLock(&queuePtr->lock); taskPtr->signal |= TASK_DONE; Ns_MutexUnlock(&queuePtr->lock); broadcast = 1; } if (taskPtr->flags & TASK_WAIT) { if (max <= nfds) { max = nfds + 100; pfds = ns_realloc(pfds, (size_t) max); } taskPtr->idx = nfds; pfds[nfds].fd = taskPtr->sock; pfds[nfds].events = taskPtr->events; pfds[nfds].revents = 0; if ((taskPtr->flags & TASK_TIMEOUT) && (timeoutPtr == NULL || Ns_DiffTime(&taskPtr->timeout, timeoutPtr, NULL) < 0)) { timeoutPtr = &taskPtr->timeout; } taskPtr->nextWaitPtr = firstWaitPtr; firstWaitPtr = taskPtr; ++nfds; } taskPtr = nextPtr; } /* * Signal other threads which may be waiting on tasks to complete. */ if (broadcast) { Ns_CondBroadcast(&queuePtr->cond); } /* * Break now if shutting down now that all signals have been processed. */ if (shutdown) { break; } /* * Poll sockets and drain the trigger pipe if necessary. */ n = NsPoll(pfds, nfds, timeoutPtr); if ((pfds[0].revents & POLLIN) && recv(pfds[0].fd, &c, 1, 0) != 1) { Ns_Fatal("queue: trigger read() failed: %s", ns_sockstrerror(ns_sockerrno)); } /* * Execute any ready events or timeouts for waiting tasks. */ Ns_GetTime(&now); taskPtr = firstWaitPtr; while (taskPtr != NULL) { RunTask(taskPtr, pfds[taskPtr->idx].revents, &now); taskPtr = taskPtr->nextWaitPtr; } } Ns_Log(Notice, "shutdown pending"); /* * Call exit for all remaining tasks. */ taskPtr = firstWaitPtr; while (taskPtr != NULL) { Call(taskPtr, NS_SOCK_EXIT); taskPtr = taskPtr->nextWaitPtr; } /* * Signal all tasks done and shutdown complete. */ Ns_MutexLock(&queuePtr->lock); while ((taskPtr = firstWaitPtr) != NULL) { firstWaitPtr = taskPtr->nextWaitPtr; taskPtr->signal |= TASK_DONE; } queuePtr->stopped = 1; Ns_MutexUnlock(&queuePtr->lock); Ns_CondBroadcast(&queuePtr->cond); Ns_Log(Notice, "shutdown complete"); } Index: sock.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/sock.c,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** sock.c 12 Nov 2005 20:50:33 -0000 1.6 --- sock.c 4 Jan 2006 10:15:52 -0000 1.7 *************** *** 713,716 **** --- 713,780 ---- *---------------------------------------------------------------------- * + * NsPoll -- + * + * Poll file descriptors using an absolute timeout and restarting + * after any interrupts which may be received. + * + * Results: + * See poll(2) man page. + * + * Side effects: + * See poll(2) man page. + * + *---------------------------------------------------------------------- + */ + + int + NsPoll(struct pollfd *pfds, int nfds, Ns_Time *timeoutPtr) + { + Ns_Time now, diff; + int i, n, ms; + + /* + * Clear revents. + */ + + for (i = 0; i < nfds; ++i) { + pfds[i].revents = 0; + } + + /* + * Determine relative time from absolute time and continue polling + * if any interrupts are received. + */ + + do { + if (timeoutPtr == NULL) { + ms = -1; + } else { + Ns_GetTime(&now); + if (Ns_DiffTime(timeoutPtr, &now, &diff) <= 0) { + ms = 0; + } else { + ms = diff.sec * 1000 + diff.usec / 1000; + } + } + n = poll(pfds, (size_t) nfds, ms); + } while (n < 0 && ns_sockerrno == EINTR); + + /* + * Poll errors are not tolerated in as they must indicate + * a code error which if ignored could lead to data loss and/or + * endless polling loops and error messages. + */ + + if (n < 0) { + Ns_Fatal("poll() failed: %s", ns_sockstrerror(ns_sockerrno)); + } + + return n; + } + + + /* + *---------------------------------------------------------------------- + * * SockSetup -- * |
From: Stephen D. <sd...@us...> - 2006-01-04 10:16:03
|
Update of /cvsroot/naviserver/naviserver In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28689 Modified Files: ChangeLog Log Message: * include/ns.h: * nsd/nsd.h: * nsd/Makefile: * nsd/nsmain.c: * nsd/sock.c: * nsd/task.c: Backport AOLserver task queues. Callbacks are registered to run in a seperate thread in response to socket read/write events. Index: ChangeLog =================================================================== RCS file: /cvsroot/naviserver/naviserver/ChangeLog,v retrieving revision 1.263 retrieving revision 1.264 diff -C2 -d -r1.263 -r1.264 *** ChangeLog 30 Dec 2005 11:26:42 -0000 1.263 --- ChangeLog 4 Jan 2006 10:15:52 -0000 1.264 *************** *** 1,2 **** --- 1,13 ---- + 2006-01-04 Stephen Deasey <sd...@us...> + + * include/ns.h: + * nsd/nsd.h: + * nsd/Makefile: + * nsd/nsmain.c: + * nsd/sock.c: + * nsd/task.c: Backport AOLserver task queues. Callbacks are + registered to run in a seperate thread in response to socket + read/write events. + 2005-12-30 Stephen Deasey <sd...@us...> |
From: Stephen D. <sd...@us...> - 2005-12-30 11:26:51
|
Update of /cvsroot/naviserver/naviserver/nsd In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2780/nsd Modified Files: init.c op.c url2file.c urlspace.c Log Message: 2005-12-30 Stephen Deasey <sd...@us...> * include/ns.h: * nsd/init.c: * nsd/urlspace.c: * tests/url2file.test: Split the urlspace by key ID and remove the global lock. Remove unused Ns_ServerSpecific*() routines. Make NsUrlSpecificWalk() emit an entry for both inherit and noinherit data, identifying each with a keyword. Don't emit the server name, which is redundant, and separate the URL from the filter. (RFE: 1377113) Index: urlspace.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/urlspace.c,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** urlspace.c 2 Oct 2005 22:23:10 -0000 1.6 --- urlspace.c 30 Dec 2005 11:26:42 -0000 1.7 *************** *** 43,51 **** NS_RCSID("@(#) $Header$"); - /* - * Size of stack to keep track of server/method/url/... node path - */ ! #define STACK_SIZE 512 /* --- 43,49 ---- [...2245 lines suppressed...] - { - int i; - char *stack[STACK_SIZE]; - - memset(stack, 0, sizeof(stack)); - Ns_MutexLock(&lock); - #ifndef __URLSPACE_OPTIMIZE__ - for (i = 0; i < (&urlspace.byuse)->n; i++) { - Channel *channelPtr; - channelPtr = (Channel *) Ns_IndexEl(&urlspace.byuse, i); - #else - for (i = ((&urlspace.byname)->n - 1); i >= 0; i--) { - Channel *channelPtr; - channelPtr = (Channel *) Ns_IndexEl(&urlspace.byname, i); - #endif - WalkTrie(&channelPtr->trie, id, server, func, dsPtr, stack, channelPtr->filter); - } - Ns_MutexUnlock(&lock); - } --- 1744,1746 ---- Index: op.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/op.c,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** op.c 5 Dec 2005 08:40:23 -0000 1.6 --- op.c 30 Dec 2005 11:26:42 -0000 1.7 *************** *** 56,59 **** --- 56,60 ---- */ + static void WalkCallback(Tcl_DString *dsPtr, void *arg); static void FreeReq(void *arg); *************** *** 468,516 **** /* *---------------------------------------------------------------------- * ! * FreeReq -- ! * ! * URL space callback to delete a request structure. ! * * Results: ! * None. * * Side effects: ! * Depends on request delete procedure. * *---------------------------------------------------------------------- */ ! ! static void ! FreeReq(void *arg) { ! Req *reqPtr = (Req *) arg; ! ! if (--reqPtr->refcnt == 0) { ! if (reqPtr->delete != NULL) { ! (*reqPtr->delete) (reqPtr->arg); ! } ! ns_free(reqPtr); } } ! /* ! *---------------------------------------------------------------------- ! * ! * NsRequestArgProc -- ! * ! * Proc info routine to copy Tcl request proc. ! * ! * Results: ! * None. ! * ! * Side effects: ! * Will copy script to given dstring. ! * ! *---------------------------------------------------------------------- ! */ ! ! void ! NsTclRequestArgProc(Tcl_DString *dsPtr, void *arg) { Req *reqPtr = arg; --- 469,502 ---- /* *---------------------------------------------------------------------- + * NsGetRequestProcs -- * ! * Get a description of each registered request for the given ! * server. ! * * Results: ! * DString with info in Tcl list form. * * Side effects: ! * None. * *---------------------------------------------------------------------- */ ! ! void ! NsGetRequestProcs(Tcl_DString *dsPtr, CONST char *server) { ! NsServer *servPtr; ! ! servPtr = NsGetServer(server); ! if (servPtr == NULL) { ! return; } + Ns_MutexLock(&ulock); + NsUrlSpecificWalk(uid, servPtr->server, WalkCallback, dsPtr); + Ns_MutexUnlock(&ulock); } ! static void ! WalkCallback(Tcl_DString *dsPtr, void *arg) { Req *reqPtr = arg; *************** *** 519,549 **** } ! /* *---------------------------------------------------------------------- - * NsGetRequestProcs -- * ! * Returns information about registered requests/procs. ! * * Results: ! * DString with info as Tcl list. * * Side effects: ! * None. * *---------------------------------------------------------------------- */ ! ! void ! NsGetRequestProcs(Tcl_DString *dsPtr, CONST char *server) { ! NsServer *servPtr; ! ! servPtr = NsGetServer(server); ! if (servPtr == NULL) { ! return; } - Ns_MutexLock(&ulock); - NsUrlSpecificWalk(uid, servPtr->server, NsTclRequestArgProc, dsPtr); - Ns_MutexUnlock(&ulock); } --- 505,535 ---- } ! /* *---------------------------------------------------------------------- * ! * FreeReq -- ! * ! * URL space callback to delete a request structure. ! * * Results: ! * None. * * Side effects: ! * Depends on request delete procedure. * *---------------------------------------------------------------------- */ ! ! static void ! FreeReq(void *arg) { ! Req *reqPtr = (Req *) arg; ! ! if (--reqPtr->refcnt == 0) { ! if (reqPtr->delete != NULL) { ! (*reqPtr->delete) (reqPtr->arg); ! } ! ns_free(reqPtr); } } Index: init.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/init.c,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** init.c 30 Dec 2005 11:07:34 -0000 1.7 --- init.c 30 Dec 2005 11:26:42 -0000 1.8 *************** *** 80,84 **** NsInitSched(); NsInitTcl(); - NsInitUrlSpace(); NsInitRequests(); NsInitUrl2File(); --- 80,83 ---- Index: url2file.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/url2file.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** url2file.c 7 Nov 2005 03:19:05 -0000 1.1 --- url2file.c 30 Dec 2005 11:26:42 -0000 1.2 *************** *** 68,72 **** static Ns_Callback FreeMount; static void FreeUrl2File(void *arg); ! static void Url2FileProcInfo(Ns_DString *dsPtr, void *arg); /* --- 68,72 ---- static Ns_Callback FreeMount; static void FreeUrl2File(void *arg); ! static void WalkCallback(Ns_DString *dsPtr, void *arg); /* *************** *** 583,587 **** *---------------------------------------------------------------------- * ! * NsGetUrl2FileProcsProcs -- * * Append information about registered url2file procs to dstring. --- 583,587 ---- *---------------------------------------------------------------------- * ! * NsGetUrl2FileProcs -- * * Append information about registered url2file procs to dstring. *************** *** 600,609 **** { Ns_MutexLock(&ulock); ! NsUrlSpecificWalk(uid, server, Url2FileProcInfo, dsPtr); Ns_MutexUnlock(&ulock); } static void ! Url2FileProcInfo(Ns_DString *dsPtr, void *arg) { Url2File *u2fPtr = arg; --- 600,609 ---- { Ns_MutexLock(&ulock); ! NsUrlSpecificWalk(uid, server, WalkCallback, dsPtr); Ns_MutexUnlock(&ulock); } static void ! WalkCallback(Ns_DString *dsPtr, void *arg) { Url2File *u2fPtr = arg; |
From: Stephen D. <sd...@us...> - 2005-12-30 11:26:50
|
Update of /cvsroot/naviserver/naviserver/tests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2780/tests Modified Files: url2file.test Log Message: 2005-12-30 Stephen Deasey <sd...@us...> * include/ns.h: * nsd/init.c: * nsd/urlspace.c: * tests/url2file.test: Split the urlspace by key ID and remove the global lock. Remove unused Ns_ServerSpecific*() routines. Make NsUrlSpecificWalk() emit an entry for both inherit and noinherit data, identifying each with a keyword. Don't emit the server name, which is redundant, and separate the URL from the filter. (RFE: 1377113) Index: url2file.test =================================================================== RCS file: /cvsroot/naviserver/naviserver/tests/url2file.test,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** url2file.test 7 Nov 2005 03:19:05 -0000 1.1 --- url2file.test 30 Dec 2005 11:26:42 -0000 1.2 *************** *** 117,123 **** ns_unregister_url2file /url1 ns_unregister_url2file /url2 ! } -result [list [list [ns_info server] x /url1* ns:tclurl2file script] \ ! [list [ns_info server] x /url2* ns:mounturl2file /base /url2] \ ! [list [ns_info server] x * ns:fasturl2file [ns_info server]] ] --- 117,123 ---- ns_unregister_url2file /url1 ns_unregister_url2file /url2 ! } -result [list [list x /url1 * inherit ns:tclurl2file script] \ ! [list x /url2 * inherit ns:mounturl2file /base /url2] \ ! [list x / * inherit ns:fasturl2file [ns_info server]] ] |
From: Stephen D. <sd...@us...> - 2005-12-30 11:26:50
|
Update of /cvsroot/naviserver/naviserver In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2780 Modified Files: ChangeLog Log Message: 2005-12-30 Stephen Deasey <sd...@us...> * include/ns.h: * nsd/init.c: * nsd/urlspace.c: * tests/url2file.test: Split the urlspace by key ID and remove the global lock. Remove unused Ns_ServerSpecific*() routines. Make NsUrlSpecificWalk() emit an entry for both inherit and noinherit data, identifying each with a keyword. Don't emit the server name, which is redundant, and separate the URL from the filter. (RFE: 1377113) Index: ChangeLog =================================================================== RCS file: /cvsroot/naviserver/naviserver/ChangeLog,v retrieving revision 1.262 retrieving revision 1.263 diff -C2 -d -r1.262 -r1.263 *** ChangeLog 30 Dec 2005 11:07:33 -0000 1.262 --- ChangeLog 30 Dec 2005 11:26:42 -0000 1.263 *************** *** 2,5 **** --- 2,19 ---- * include/ns.h: + * nsd/init.c: + * nsd/urlspace.c: + * tests/url2file.test: Split the urlspace by key ID and remove the + global lock. Remove unused Ns_ServerSpecific*() routines. + + Make NsUrlSpecificWalk() emit an entry for both inherit and + noinherit data, identifying each with a keyword. Don't emit the + server name, which is redundant, and separate the URL from the + filter. (RFE: 1377113) + + * nsd/op.c: + * nsd/url2file.c: Clarify naming of urlspecifc walk callbacks. + + * include/ns.h: * nsd/nsd.h: * nsd/init.c: |
From: Stephen D. <sd...@us...> - 2005-12-30 11:26:50
|
Update of /cvsroot/naviserver/naviserver/include In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2780/include Modified Files: ns.h Log Message: 2005-12-30 Stephen Deasey <sd...@us...> * include/ns.h: * nsd/init.c: * nsd/urlspace.c: * tests/url2file.test: Split the urlspace by key ID and remove the global lock. Remove unused Ns_ServerSpecific*() routines. Make NsUrlSpecificWalk() emit an entry for both inherit and noinherit data, identifying each with a keyword. Don't emit the server name, which is redundant, and separate the URL from the filter. (RFE: 1377113) Index: ns.h =================================================================== RCS file: /cvsroot/naviserver/naviserver/include/ns.h,v retrieving revision 1.65 retrieving revision 1.66 diff -C2 -d -r1.65 -r1.66 *** ns.h 30 Dec 2005 11:07:33 -0000 1.65 --- ns.h 30 Dec 2005 11:26:42 -0000 1.66 *************** *** 1930,1961 **** NS_EXTERN void Ns_UrlSpecificSet(CONST char *server, CONST char *method, CONST char *url, int id, ! void *data, int flags, void (*deletefunc)(void *)); NS_EXTERN void * ! Ns_UrlSpecificGet(CONST char *server, CONST char *method, CONST char *url, int id); NS_EXTERN void * ! Ns_UrlSpecificGetFast(CONST char *server, CONST char *method, CONST char *url, int id); NS_EXTERN void * Ns_UrlSpecificGetExact(CONST char *server, CONST char *method, CONST char *url, ! int id, int flags); NS_EXTERN void * Ns_UrlSpecificDestroy(CONST char *server, CONST char *method, CONST char *url, ! int id, int flags); ! ! NS_EXTERN int ! Ns_ServerSpecificAlloc(void); ! ! NS_EXTERN void ! Ns_ServerSpecificSet(CONST char *handle, int id, void *data, int flags, ! void (*deletefunc)(void *)); ! ! NS_EXTERN void * ! Ns_ServerSpecificGet(CONST char *handle, int id); ! ! NS_EXTERN void * ! Ns_ServerSpecificDestroy(CONST char *handle, int id, int flags); /* --- 1930,1953 ---- NS_EXTERN void Ns_UrlSpecificSet(CONST char *server, CONST char *method, CONST char *url, int id, ! void *data, int flags, void (*deletefunc)(void *)) ! NS_GNUC_NONNULL(1) NS_GNUC_NONNULL(2) NS_GNUC_NONNULL(3) NS_GNUC_NONNULL(5); NS_EXTERN void * ! Ns_UrlSpecificGet(CONST char *server, CONST char *method, CONST char *url, int id) ! NS_GNUC_NONNULL(1) NS_GNUC_NONNULL(2) NS_GNUC_NONNULL(3); NS_EXTERN void * ! Ns_UrlSpecificGetFast(CONST char *server, CONST char *method, CONST char *url, int id) ! NS_GNUC_NONNULL(1) NS_GNUC_NONNULL(2) NS_GNUC_NONNULL(3); NS_EXTERN void * Ns_UrlSpecificGetExact(CONST char *server, CONST char *method, CONST char *url, ! int id, int flags) ! NS_GNUC_NONNULL(1) NS_GNUC_NONNULL(2) NS_GNUC_NONNULL(3); NS_EXTERN void * Ns_UrlSpecificDestroy(CONST char *server, CONST char *method, CONST char *url, ! int id, int flags) ! NS_GNUC_NONNULL(1) NS_GNUC_NONNULL(2) NS_GNUC_NONNULL(3); /* |
From: Stephen D. <sd...@us...> - 2005-12-30 11:07:44
|
Update of /cvsroot/naviserver/naviserver/nsd In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32584/nsd Modified Files: Makefile cache.c init.c nsd.h proc.c server.c tclcmds.c Added Files: tclcache.c Log Message: 2005-12-30 Stephen Deasey <sd...@us...> * include/ns.h: * nsd/nsd.h: * nsd/init.c: * nsd/proc.c: * nsd/cache.c: Global hash of cache names removed; access no longer available via Ns_CacheFind() or ns_cache_names. Caches have unique locking requirements and lifetimes which could be violated by e.g. running ns_cache_stats on a thread local cache as the thread is exiting. New Ns_CacheCreateEx() allows creating a cache which has both a size and a time limit. Caches with time limits are calculated differently. Previous behaviour was to periodically check the last access time of each cache entry and flush those which had expired. A busy cache could grow without bound. New behaviour is to check for expirey each time an entry is retrieved from the cache. All caches can (and should) be size limited. Timeouts may be specified per cache and per entry using new Ns_CacheSetValueExpires(). Ns_CacheFlush() now returns the number of entries flushed. New Ns_CacheStats() takes over from ns_cache_stats for non-Tcl caches. Stats are returned in Tcl "array get" format. Removed Ns_CacheMalloc(), Ns_CacheFree() and Ns_CacheName(). Move Tcl commands to tclcache.c. * nsd/Makefile: * nsd/tclcmds.c: * nsd/tclcache.c: * tests/ns_cache.test: Add new Tcl commands ns_cache_create, _eval, _append, _lappend, and _incr. (RFE# 1119257) Old commands ns_cache_names, _keys, _flush and _stats now only work on Tcl caches. ns_cache_size has been removed; the size is now reported along with other statistics. These commands now only work on Tcl caches. * tcl/cache.tcl: New ns_memoize and related commands which act just like ns_cache_eval but use the script as a key into the memoize cache. Index: init.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/init.c,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** init.c 7 Nov 2005 03:17:55 -0000 1.6 --- init.c 30 Dec 2005 11:07:34 -0000 1.7 *************** *** 69,73 **** NsInitBinder(); NsInitLog(); - NsInitCache(); NsInitConf(); NsInitEncodings(); --- 69,72 ---- Index: nsd.h =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/nsd.h,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -d -r1.41 -r1.42 *** nsd.h 11 Dec 2005 11:19:50 -0000 1.41 --- nsd.h 30 Dec 2005 11:07:34 -0000 1.42 *************** *** 639,642 **** --- 639,645 ---- Tcl_HashTable runTable; CONST char **errorLogHeaders; + Tcl_HashTable caches; + Ns_Mutex cachelock; + int cacheTimeout; } tcl; *************** *** 873,878 **** extern Ns_ThreadProc NsTclThread; extern Ns_ArgProc NsTclThreadArgProc; - extern Ns_Callback NsCachePurge; - extern Ns_ArgProc NsCacheArgProc; extern Ns_SockProc NsTclSockProc; extern Ns_ArgProc NsTclSockArgProc; --- 876,879 ---- Index: cache.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/cache.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** cache.c 10 Jun 2005 17:58:38 -0000 1.2 --- cache.c 30 Dec 2005 11:07:34 -0000 1.3 *************** *** 32,36 **** * cache.c -- * ! * Routines for a simple cache used by fastpath and Adp. */ --- 32,36 ---- * cache.c -- * ! * Size and time limited caches. */ [...1909 lines suppressed...] ! Ns_IncrTime(&expired, -cachePtr->timeout, 0); ! while ((ePtr = cachePtr->lastEntryPtr) != NULL) { ! if (ePtr->mtime.sec > expired.sec) { ! break; ! } ! if (ePtr->mtime.sec == expired.sec ! && ePtr->mtime.usec > expired.usec) { ! break; ! } ! Ns_CacheFlushEntry((Ns_Entry *) ePtr); ! } } - Ns_MutexUnlock(&cachePtr->lock); } --- 896,900 ---- ePtr->cachePtr->firstEntryPtr = ePtr; if (ePtr->cachePtr->lastEntryPtr == NULL) { ! ePtr->cachePtr->lastEntryPtr = ePtr; } } Index: Makefile =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/Makefile,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** Makefile 7 Nov 2005 03:17:55 -0000 1.7 --- Makefile 30 Dec 2005 11:07:34 -0000 1.8 *************** *** 46,50 **** quotehtml.o random.o request.o return.o rollfile.o sched.o \ server.o set.o sock.o sockcallback.o str.o \ ! tclcallbacks.o tclcmds.o tclconf.o tclenv.o tclfile.o tclhttp.o tclimg.o \ tclinit.o tcljob.o tclmisc.o tclobj.o tclobjv.o tclrequest.o tclresp.o \ tclsched.o tclset.o tclshare.o tclsock.o tclthread.o tcltime.o tclvar.o \ --- 46,50 ---- quotehtml.o random.o request.o return.o rollfile.o sched.o \ server.o set.o sock.o sockcallback.o str.o \ ! tclcache.o tclcallbacks.o tclcmds.o tclconf.o tclenv.o tclfile.o tclhttp.o tclimg.o \ tclinit.o tcljob.o tclmisc.o tclobj.o tclobjv.o tclrequest.o tclresp.o \ tclsched.o tclset.o tclshare.o tclsock.o tclthread.o tcltime.o tclvar.o \ --- NEW FILE: tclcache.c --- /* * The contents of this file are subject to the AOLserver Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://aolserver.com/. * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is AOLserver Code and related documentation * distributed by AOL. * * The Initial Developer of the Original Code is America Online, * Inc. Portions created by AOL are Copyright (C) 1999 America Online, * Inc. All Rights Reserved. * * Alternatively, the contents of this file may be used under the terms * of the GNU General Public License (the "GPL"), in which case the * provisions of GPL are applicable instead of those above. If you wish * to allow use of your version of this file only under the terms of the * GPL and not to allow others to use your version of this file under the * License, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the GPL. * If you do not delete the provisions above, a recipient may use your * version of this file under either the License or the GPL. */ /* * tclcache.c -- * * Tcl cache commands. */ #include "nsd.h" NS_RCSID("@(#) $Header: /cvsroot/naviserver/naviserver/nsd/tclcache.c,v 1.1 2005/12/30 11:07:34 sdeasey Exp $"); /* * Local functions defined in this file */ static int CacheAppendObjCmd(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int append); static Ns_Entry *CreateEntry(NsInterp *itPtr, Ns_Cache *cache, char *key, int *newPtr, int timeout); static void SetEntry(Tcl_Interp *interp, Ns_Entry *entry, Tcl_Obj *valObj, int ttl); static Ns_ObjvProc ObjvCache; /* *---------------------------------------------------------------------- * * NsTclCacheCreateObjCmd -- * * Create a new Tcl cache. * * Results: * TCL result. * * Side effects: * None. * *---------------------------------------------------------------------- */ int NsTclCacheCreateObjCmd(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { NsInterp *itPtr = arg; NsServer *servPtr = itPtr->servPtr; Tcl_HashEntry *hPtr; Ns_Cache *cache; char *name; int new, maxSize, ttl = 0; Ns_ObjvSpec opts[] = { {"-ttl", Ns_ObjvInt, &ttl, NULL}, {"--", Ns_ObjvBreak, NULL, NULL}, {NULL, NULL, NULL, NULL} }; Ns_ObjvSpec args[] = { {"cache", Ns_ObjvString, &name, NULL}, {"size", Ns_ObjvInt, &maxSize, NULL}, {NULL, NULL, NULL, NULL} }; if (Ns_ParseObjv(opts, args, interp, 1, objc, objv) != NS_OK) { return TCL_ERROR; } Ns_MutexLock(&servPtr->tcl.cachelock); hPtr = Tcl_CreateHashEntry(&servPtr->tcl.caches, name, &new); if (new) { cache = Ns_CacheCreateEx(name, TCL_STRING_KEYS, ttl, maxSize, ns_free); Tcl_SetHashValue(hPtr, cache); } Ns_MutexUnlock(&servPtr->tcl.cachelock); if (!new) { Tcl_AppendResult(interp, "duplicate cache name: ", name, NULL); return TCL_ERROR; } return TCL_OK; } /* *---------------------------------------------------------------------- * * NsTclCacheEvalObjCmd -- * * Get data from a cache by key. If key is not present or data * is stale, script is evaluated (with args appended, if present), * and the result is stored in the cache and returned. Script * errors are propagated. * * Results: * TCL result. * * Side effects: * None. * *---------------------------------------------------------------------- */ int NsTclCacheEvalObjCmd(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { NsInterp *itPtr = arg; Ns_Cache *cache; Ns_Entry *entry; char *key; int new, status = TCL_OK; int nargs, timeout = -1, ttl = 0; Ns_ObjvSpec opts[] = { {"-timeout", Ns_ObjvInt, &timeout, NULL}, {"-ttl", Ns_ObjvInt, &ttl, NULL}, {"--", Ns_ObjvBreak, NULL, NULL}, {NULL, NULL, NULL, NULL} }; Ns_ObjvSpec args[] = { {"cache", ObjvCache, &cache, arg}, {"key", Ns_ObjvString, &key, NULL}, {"args", Ns_ObjvArgs, &nargs, NULL}, {NULL, NULL, NULL, NULL} }; if (Ns_ParseObjv(opts, args, interp, 1, objc, objv) != NS_OK) { return TCL_ERROR; } if ((entry = CreateEntry(itPtr, cache, key, &new, timeout)) == NULL) { return TCL_ERROR; } if (!new) { Tcl_SetStringObj(Tcl_GetObjResult(interp), Ns_CacheGetValue(entry), Ns_CacheGetSize(entry)); } else { Ns_CacheUnlock(cache); if (nargs == 1) { status = Tcl_EvalObjEx(interp, objv[objc-1], 0); } else { status = Tcl_EvalObjv(interp, nargs, objv + (objc-nargs), 0); } Ns_CacheLock(cache); entry = Ns_CacheCreateEntry(cache, key, &new); if (status != TCL_OK && status != TCL_RETURN) { status = TCL_ERROR; Ns_CacheFlushEntry(entry); } else { status = TCL_OK; SetEntry(interp, entry, NULL, ttl); } Ns_CacheBroadcast(cache); } Ns_CacheUnlock(cache); return status; } /* *---------------------------------------------------------------------- * * NsTclCacheIncrObjCmd -- * * Treat the value of the cached object as in integer and * increment it. No value is trated as starting at zero.a * * Results: * TCL result. * * Side effects: * None. * *---------------------------------------------------------------------- */ int NsTclCacheIncrObjCmd(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { NsInterp *itPtr = arg; Ns_Cache *cache; Ns_Entry *entry; char *key; int new, cur, incr = 1; int timeout = -1, ttl = 0; Ns_ObjvSpec opts[] = { {"-timeout", Ns_ObjvInt, &timeout, NULL}, {"-ttl", Ns_ObjvInt, &ttl, NULL}, {"--", Ns_ObjvBreak, NULL, NULL}, {NULL, NULL, NULL, NULL} }; Ns_ObjvSpec args[] = { {"cache", ObjvCache, &cache, arg}, {"key", Ns_ObjvString, &key, NULL}, {"?incr", Ns_ObjvInt, &incr, NULL}, {NULL, NULL, NULL, NULL} }; if (Ns_ParseObjv(opts, args, interp, 1, objc, objv) != NS_OK) { return TCL_ERROR; } if ((entry = CreateEntry(itPtr, cache, key, &new, timeout)) == NULL) { return TCL_ERROR; } if (new) { cur = 0; } else if (Tcl_GetInt(interp, Ns_CacheGetValue(entry), &cur) != TCL_OK) { Ns_CacheUnlock(cache); return TCL_ERROR; } SetEntry(interp, entry, Tcl_NewIntObj(cur + incr), ttl); Ns_CacheUnlock(cache); return TCL_OK; } /* *---------------------------------------------------------------------- * * NsTclCacheAppendObjCmd, NsTclCacheLappendObjCmd -- * * Append one or more elements to cache value. * * Results: * TCL result. * * Side effects: * None. * *---------------------------------------------------------------------- */ int NsTclCacheAppendObjCmd(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { return CacheAppendObjCmd(arg, interp, objc, objv, 1); } int NsTclCacheLappendObjCmd(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { return CacheAppendObjCmd(arg, interp, objc, objv, 0); } static int CacheAppendObjCmd(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int append) { NsInterp *itPtr = arg; Ns_Cache *cache; Ns_Entry *entry; Tcl_Obj *resultObj; char *key; int i, new, nelements; int timeout = -1, ttl = 0; Ns_ObjvSpec opts[] = { {"-timeout", Ns_ObjvInt, &timeout, NULL}, {"-ttl", Ns_ObjvInt, &ttl, NULL}, {"--", Ns_ObjvBreak, NULL, NULL}, {NULL, NULL, NULL, NULL} }; Ns_ObjvSpec args[] = { {"cache", ObjvCache, &cache, arg}, {"key", Ns_ObjvString, &key, NULL}, {"args", Ns_ObjvArgs, &nelements, NULL}, {NULL, NULL, NULL, NULL} }; if (Ns_ParseObjv(opts, args, interp, 1, objc, objv) != NS_OK) { return TCL_ERROR; } if ((entry = CreateEntry(itPtr, cache, key, &new, timeout)) == NULL) { return TCL_ERROR; } resultObj = Tcl_GetObjResult(interp); if (!new) { Tcl_SetStringObj(resultObj, Ns_CacheGetValue(entry), Ns_CacheGetSize(entry)); } for (i = objc - nelements; i < objc; i++) { if (append) { Tcl_AppendObjToObj(resultObj, objv[i]); } else if (Tcl_ListObjAppendElement(interp, resultObj, objv[i]) != TCL_OK) { Ns_CacheUnlock(cache); return TCL_ERROR; } } SetEntry(interp, entry, NULL, ttl); Ns_CacheUnlock(cache); return TCL_OK; } /* *---------------------------------------------------------------------- * * NsTclCacheNamesObjCmd -- * * Spit back a list of cache names. * * Results: * Tcl result. * * Side effects: * A list of cache names will be appended to the interp result. * *---------------------------------------------------------------------- */ int NsTclCacheNamesObjCmd(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { NsInterp *itPtr = arg; NsServer *servPtr = itPtr->servPtr; Tcl_HashEntry *hPtr; Tcl_HashSearch search; Ns_MutexLock(&servPtr->tcl.cachelock); hPtr = Tcl_FirstHashEntry(&servPtr->tcl.caches, &search); while (hPtr != NULL) { Tcl_AppendElement(interp, Tcl_GetHashKey(&servPtr->tcl.caches, hPtr)); hPtr = Tcl_NextHashEntry(&search); } Ns_MutexUnlock(&servPtr->tcl.cachelock); return TCL_OK; } /* *---------------------------------------------------------------------- * * NsTclCacheKeysObjCmd -- * * Get a list of all keys in a cache, or only those matching * pattern, if given. * * Results: * TCL result. * * Side effects: * None. * *---------------------------------------------------------------------- */ int NsTclCacheKeysObjCmd(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { Ns_Cache *cache; Ns_Entry *entry; Ns_CacheSearch search; char *key, *pattern = NULL; Ns_DString ds; Ns_ObjvSpec args[] = { {"cache", ObjvCache, &cache, arg}, {"?pattern", Ns_ObjvString, &pattern, NULL}, {NULL, NULL, NULL, NULL} }; if (Ns_ParseObjv(NULL, args, interp, 1, objc, objv) != NS_OK) { return TCL_ERROR; } Ns_DStringInit(&ds); Ns_CacheLock(cache); entry = Ns_CacheFirstEntry(cache, &search); while (entry != NULL) { key = Ns_CacheKey(entry); if (pattern == NULL || Tcl_StringMatch(key, pattern)) { Tcl_AppendElement(interp, key); } entry = Ns_CacheNextEntry(&search); } Ns_CacheUnlock(cache); Ns_DStringFree(&ds); return TCL_OK; } /* *---------------------------------------------------------------------- * * NsTclCacheFlushObjCmd -- * * Flush all entries from a cache, or the single entry identified * by key. Return the number of entries flushed. * * Results: * TCL result. * * Side effects: * None. * *---------------------------------------------------------------------- */ int NsTclCacheFlushObjCmd(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { Ns_Cache *cache; Ns_Entry *entry; Ns_CacheSearch search; char *key, *pattern; int i, nflushed = 0, glob = NS_FALSE, npatterns = 0; Ns_ObjvSpec opts[] = { {"-glob", Ns_ObjvBool, &glob, (void *) NS_TRUE}, {"--", Ns_ObjvBreak, NULL, NULL}, {NULL, NULL, NULL, NULL} }; Ns_ObjvSpec args[] = { {"cache", ObjvCache, &cache, arg}, {"?args", Ns_ObjvArgs, &npatterns, NULL}, {NULL, NULL, NULL, NULL} }; if (Ns_ParseObjv(opts, args, interp, 1, objc, objv) != NS_OK) { return TCL_ERROR; } Ns_CacheLock(cache); if (npatterns == 0) { nflushed = Ns_CacheFlush(cache); } else if (!glob) { for (i = npatterns; i > 0; i--) { entry = Ns_CacheFindEntry(cache, Tcl_GetString(objv[objc-i])); if (entry != NULL) { Ns_CacheFlushEntry(entry); nflushed++; } } } else { entry = Ns_CacheFirstEntry(cache, &search); while (entry != NULL) { key = Ns_CacheKey(entry); for (i = npatterns; i > 0; i--) { pattern = Tcl_GetString(objv[objc-i]); if (Tcl_StringMatch(key, pattern)) { Ns_CacheFlushEntry(entry); nflushed++; break; } } entry = Ns_CacheNextEntry(&search); } } Ns_CacheUnlock(cache); Tcl_SetIntObj(Tcl_GetObjResult(interp), nflushed); return TCL_OK; } /* *---------------------------------------------------------------------- * * NsTclCacheStatsObjCmds -- * * Returns stats on a cache. * * Results: * Tcl result. * * Side effects: * Results will be appended to interp. * *---------------------------------------------------------------------- */ int NsTclCacheStatsObjCmd(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { Ns_Cache *cache; Ns_DString ds; Ns_ObjvSpec args[] = { {"cache", ObjvCache, &cache, arg}, {NULL, NULL, NULL, NULL} }; if (Ns_ParseObjv(NULL, args, interp, 1, objc, objv) != NS_OK) { return TCL_ERROR; } Ns_DStringInit(&ds); Ns_CacheLock(cache); Ns_CacheStats(cache, &ds); Ns_CacheUnlock(cache); Tcl_DStringResult(interp, &ds); return TCL_OK; } /* *---------------------------------------------------------------------- * * CreateEntry -- * * Lock the cache and create a new entry or return existing entry, * waiting up to timeout seconds for another thread to complete * an update. * * Results: * Pointer to entry, or NULL on flush or timeout. * * Side effects: * Cache will be left locked if function returns entry. * *---------------------------------------------------------------------- */ static Ns_Entry * CreateEntry(NsInterp *itPtr, Ns_Cache *cache, char *key, int *newPtr, int timeout) { Ns_Entry *entry; if (timeout < 0) { timeout = itPtr->servPtr->tcl.cacheTimeout; } Ns_CacheLock(cache); entry = Ns_CacheWaitCreateEntry(cache, key, newPtr, timeout); if (entry == NULL) { Ns_CacheUnlock(cache); Tcl_AppendResult(itPtr->interp, "timeout waiting for update or entry flushed: ", key, NULL); } return entry; } /* *---------------------------------------------------------------------- * * SetEntry -- * * Set the value of the cache entry using valObj. If interp * is not NULL, also set it as the Tcl result. * * Results: * None. * * Side effects: * valObj will be owned by interp if not NULL. * *---------------------------------------------------------------------- */ static void SetEntry(Tcl_Interp *interp, Ns_Entry *entry, Tcl_Obj *valObj, int ttl) { char *string, *value; int len; Tcl_Obj *objPtr = valObj; if (objPtr == NULL) { objPtr = Tcl_GetObjResult(interp); } string = Tcl_GetStringFromObj(objPtr, &len); value = ns_malloc(len + 1); memcpy(value, string, len + 1); Ns_CacheSetValueExpires(entry, value, len, ttl); if (valObj != NULL) { Tcl_SetObjResult(interp, valObj); } } /* *---------------------------------------------------------------------- * * ObjvCache -- * * Get a cache by name. * * Results: * TCL_OK or TCL_ERROR. * * Side effects: * Tcl obj will be converted to ns:cache type. * *---------------------------------------------------------------------- */ static int ObjvCache(Ns_ObjvSpec *spec, Tcl_Interp *interp, int *objcPtr, Tcl_Obj *CONST objv[]) { Ns_Cache **cachePtrPtr = spec->dest; NsInterp *itPtr = spec->arg; NsServer *servPtr = itPtr->servPtr; Tcl_HashEntry *hPtr; static CONST char *cacheType = "ns:cache"; if (*objcPtr < 1) { return TCL_ERROR; } if (Ns_TclGetOpaqueFromObj(objv[0], cacheType, (void **) cachePtrPtr) != TCL_OK) { Ns_MutexLock(&servPtr->tcl.cachelock); hPtr = Tcl_FindHashEntry(&servPtr->tcl.caches, Tcl_GetString(objv[0])); Ns_MutexUnlock(&servPtr->tcl.cachelock); if (hPtr == NULL) { Tcl_AppendResult(interp, "no such cache: ", Tcl_GetString(objv[0]), NULL); return TCL_ERROR; } *cachePtrPtr = Tcl_GetHashValue(hPtr); Ns_TclSetOpaqueObj(objv[0], cacheType, *cachePtrPtr); } *objcPtr -= 1; return TCL_OK; } Index: server.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/server.c,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** server.c 11 Dec 2005 04:44:05 -0000 1.15 --- server.c 30 Dec 2005 11:07:34 -0000 1.16 *************** *** 293,296 **** --- 293,300 ---- Ns_RWLockInit(&servPtr->tcl.lock); Tcl_InitHashTable(&servPtr->tcl.runTable, TCL_STRING_KEYS); + Ns_MutexInit(&servPtr->tcl.cachelock); + Tcl_InitHashTable(&servPtr->tcl.caches, TCL_STRING_KEYS); + servPtr->tcl.cacheTimeout = + Ns_ConfigIntRange(path, "cachetimeout", 3, 0, INT_MAX); servPtr->nsv.nbuckets = Ns_ConfigIntRange(path, "nsvbuckets", 8, 1, INT_MAX); servPtr->nsv.buckets = NsTclCreateBuckets(server, servPtr->nsv.nbuckets); Index: proc.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/proc.c,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** proc.c 11 Dec 2005 11:19:50 -0000 1.11 --- proc.c 30 Dec 2005 11:07:34 -0000 1.12 *************** *** 74,78 **** {(void *) NsTclServerRoot, "ns:tclserverroot", Ns_TclCallbackArgProc}, {(void *) NsTclSockProc, "ns:tclsockcallback", NsTclSockArgProc}, - {(void *) NsCachePurge, "ns:cachepurge", NsCacheArgProc}, {(void *) NsConnThread, "ns:connthread", NsConnArgProc}, {(void *) NsTclFilterProc, "ns:tclfilter", Ns_TclCallbackArgProc}, --- 74,77 ---- Index: tclcmds.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/tclcmds.c,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** tclcmds.c 11 Dec 2005 11:19:50 -0000 1.27 --- tclcmds.c 30 Dec 2005 11:07:34 -0000 1.28 *************** *** 70,73 **** --- 70,82 ---- NsTclAtSignalObjCmd, NsTclAtStartupObjCmd, + NsTclCacheAppendObjCmd, + NsTclCacheCreateObjCmd, + NsTclCacheEvalObjCmd, + NsTclCacheFlushObjCmd, + NsTclCacheIncrObjCmd, + NsTclCacheKeysObjCmd, + NsTclCacheLappendObjCmd, + NsTclCacheNamesObjCmd, + NsTclCacheStatsObjCmd, NsTclCancelObjCmd, NsTclChanObjCmd, *************** *** 194,202 **** NsTclAdpRegisterProcCmd, NsTclAdpStatsCmd, - NsTclCacheFlushCmd, - NsTclCacheKeysCmd, - NsTclCacheNamesCmd, - NsTclCacheSizeCmd, - NsTclCacheStatsCmd, NsTclCharsetsCmd, NsTclConfigCmd, --- 203,206 ---- *************** *** 248,256 **** {"ns_base64decode", NULL, NsTclHTUUDecodeObjCmd}, {"ns_base64encode", NULL, NsTclHTUUEncodeObjCmd}, ! {"ns_cache_flush", NsTclCacheFlushCmd, NULL}, ! {"ns_cache_keys", NsTclCacheKeysCmd, NULL}, ! {"ns_cache_names", NsTclCacheNamesCmd, NULL}, ! {"ns_cache_size", NsTclCacheSizeCmd, NULL}, ! {"ns_cache_stats", NsTclCacheStatsCmd, NULL}, {"ns_cancel", NULL, NsTclCancelObjCmd}, {"ns_charsets", NsTclCharsetsCmd, NULL}, --- 252,264 ---- {"ns_base64decode", NULL, NsTclHTUUDecodeObjCmd}, {"ns_base64encode", NULL, NsTclHTUUEncodeObjCmd}, ! {"ns_cache_append", NULL, NsTclCacheAppendObjCmd}, ! {"ns_cache_create", NULL, NsTclCacheCreateObjCmd}, ! {"ns_cache_eval", NULL, NsTclCacheEvalObjCmd}, ! {"ns_cache_flush", NULL, NsTclCacheFlushObjCmd}, ! {"ns_cache_incr", NULL, NsTclCacheIncrObjCmd}, ! {"ns_cache_keys", NULL, NsTclCacheKeysObjCmd}, ! {"ns_cache_lappend", NULL, NsTclCacheLappendObjCmd}, ! {"ns_cache_names", NULL, NsTclCacheNamesObjCmd}, ! {"ns_cache_stats", NULL, NsTclCacheStatsObjCmd}, {"ns_cancel", NULL, NsTclCancelObjCmd}, {"ns_charsets", NsTclCharsetsCmd, NULL}, |
From: Stephen D. <sd...@us...> - 2005-12-30 11:07:44
|
Update of /cvsroot/naviserver/naviserver/tcl In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32584/tcl Added Files: cache.tcl Log Message: 2005-12-30 Stephen Deasey <sd...@us...> * include/ns.h: * nsd/nsd.h: * nsd/init.c: * nsd/proc.c: * nsd/cache.c: Global hash of cache names removed; access no longer available via Ns_CacheFind() or ns_cache_names. Caches have unique locking requirements and lifetimes which could be violated by e.g. running ns_cache_stats on a thread local cache as the thread is exiting. New Ns_CacheCreateEx() allows creating a cache which has both a size and a time limit. Caches with time limits are calculated differently. Previous behaviour was to periodically check the last access time of each cache entry and flush those which had expired. A busy cache could grow without bound. New behaviour is to check for expirey each time an entry is retrieved from the cache. All caches can (and should) be size limited. Timeouts may be specified per cache and per entry using new Ns_CacheSetValueExpires(). Ns_CacheFlush() now returns the number of entries flushed. New Ns_CacheStats() takes over from ns_cache_stats for non-Tcl caches. Stats are returned in Tcl "array get" format. Removed Ns_CacheMalloc(), Ns_CacheFree() and Ns_CacheName(). Move Tcl commands to tclcache.c. * nsd/Makefile: * nsd/tclcmds.c: * nsd/tclcache.c: * tests/ns_cache.test: Add new Tcl commands ns_cache_create, _eval, _append, _lappend, and _incr. (RFE# 1119257) Old commands ns_cache_names, _keys, _flush and _stats now only work on Tcl caches. ns_cache_size has been removed; the size is now reported along with other statistics. These commands now only work on Tcl caches. * tcl/cache.tcl: New ns_memoize and related commands which act just like ns_cache_eval but use the script as a key into the memoize cache. --- NEW FILE: cache.tcl --- # # The contents of this file are subject to the Mozilla Public License # Version 1.1 (the "License"); you may not use this file except in # compliance with the License. You may obtain a copy of the License at # http://www.mozilla.org/. # # Software distributed under the License is distributed on an "AS IS" # basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See # the License for the specific language governing rights and limitations # under the License. # # The Original Code is AOLserver Code and related documentation # distributed by AOL. # # The Initial Developer of the Original Code is America Online, # Inc. Portions created by AOL are Copyright (C) 1999 America Online, # Inc. All Rights Reserved. # # Alternatively, the contents of this file may be used under the terms # of the GNU General Public License (the "GPL"), in which case the # provisions of GPL are applicable instead of those above. If you wish # to allow use of your version of this file only under the terms of the # GPL and not to allow others to use your version of this file under the # License, indicate your decision by deleting the provisions above and # replace them with the notice and other provisions required by the GPL. # If you do not delete the provisions above, a recipient may use your # version of this file under either the License or the GPL. # # # $Header: /cvsroot/naviserver/naviserver/tcl/cache.tcl,v 1.1 2005/12/30 11:07:34 sdeasey Exp $ # # # cache.tcl -- # # Simple cache for procs and commands. # set path "ns/server/[ns_info server]/tcl" ns_cache_create ns:memoize \ [ns_config -int $path memoizecache [expr 1024*1024*10]] proc ns_memoize {args} { ns_parseargs {{-timeout ""} {-ttl 0} -- script args} $args if {![string equal $timeout ""]} { set timeout "-timeout $timeout" } set key [concat $script $args] eval ns_cache_eval $timeout -ttl $ttl -- ns:memoize [list $key] $script $args } proc ns_memoize_flush {{pattern ""}} { if {[string equal $pattern ""]} { return [ns_cache_flush ns:memoize] } else { return [ns_cache_flush -glob -- ns:memoize $pattern] } } proc ns_memoize_stats args { return [ns_cache_stats ns:memoize] } |
From: Stephen D. <sd...@us...> - 2005-12-30 11:07:44
|
Update of /cvsroot/naviserver/naviserver/include In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32584/include Modified Files: ns.h Log Message: 2005-12-30 Stephen Deasey <sd...@us...> * include/ns.h: * nsd/nsd.h: * nsd/init.c: * nsd/proc.c: * nsd/cache.c: Global hash of cache names removed; access no longer available via Ns_CacheFind() or ns_cache_names. Caches have unique locking requirements and lifetimes which could be violated by e.g. running ns_cache_stats on a thread local cache as the thread is exiting. New Ns_CacheCreateEx() allows creating a cache which has both a size and a time limit. Caches with time limits are calculated differently. Previous behaviour was to periodically check the last access time of each cache entry and flush those which had expired. A busy cache could grow without bound. New behaviour is to check for expirey each time an entry is retrieved from the cache. All caches can (and should) be size limited. Timeouts may be specified per cache and per entry using new Ns_CacheSetValueExpires(). Ns_CacheFlush() now returns the number of entries flushed. New Ns_CacheStats() takes over from ns_cache_stats for non-Tcl caches. Stats are returned in Tcl "array get" format. Removed Ns_CacheMalloc(), Ns_CacheFree() and Ns_CacheName(). Move Tcl commands to tclcache.c. * nsd/Makefile: * nsd/tclcmds.c: * nsd/tclcache.c: * tests/ns_cache.test: Add new Tcl commands ns_cache_create, _eval, _append, _lappend, and _incr. (RFE# 1119257) Old commands ns_cache_names, _keys, _flush and _stats now only work on Tcl caches. ns_cache_size has been removed; the size is now reported along with other statistics. These commands now only work on Tcl caches. * tcl/cache.tcl: New ns_memoize and related commands which act just like ns_cache_eval but use the script as a key into the memoize cache. Index: ns.h =================================================================== RCS file: /cvsroot/naviserver/naviserver/include/ns.h,v retrieving revision 1.64 retrieving revision 1.65 diff -C2 -d -r1.64 -r1.65 *** ns.h 11 Dec 2005 11:19:50 -0000 1.64 --- ns.h 30 Dec 2005 11:07:33 -0000 1.65 *************** *** 201,205 **** #define NS_TCL_SET_TEMPORARY NS_TCL_SET_STATIC ! #define NS_CACHE_FREE ((Ns_Callback *) (-1)) #ifdef _WIN32 --- 201,205 ---- #define NS_TCL_SET_TEMPORARY NS_TCL_SET_STATIC ! #define NS_CACHE_FREE ns_free #ifdef _WIN32 *************** *** 571,602 **** */ ! NS_EXTERN Ns_Cache *Ns_CacheCreate(char *name, int keys, time_t timeout, ! Ns_Callback *freeProc); ! NS_EXTERN Ns_Cache *Ns_CacheCreateSz(char *name, int keys, size_t maxSize, ! Ns_Callback *freeProc); ! NS_EXTERN void Ns_CacheDestroy(Ns_Cache *cache); ! NS_EXTERN Ns_Cache *Ns_CacheFind(char *name); ! NS_EXTERN void *Ns_CacheMalloc(Ns_Cache *cache, size_t len); ! NS_EXTERN void Ns_CacheFree(Ns_Cache *cache, void *bytes); ! NS_EXTERN Ns_Entry *Ns_CacheFindEntry(Ns_Cache *cache, char *key); ! NS_EXTERN Ns_Entry *Ns_CacheCreateEntry(Ns_Cache *cache, char *key, int *newPtr); ! NS_EXTERN char *Ns_CacheName(Ns_Entry *entry); ! NS_EXTERN char *Ns_CacheKey(Ns_Entry *entry); ! NS_EXTERN void *Ns_CacheGetValue(Ns_Entry *entry); ! NS_EXTERN void Ns_CacheSetValue(Ns_Entry *entry, void *value); ! NS_EXTERN void Ns_CacheSetValueSz(Ns_Entry *entry, void *value, size_t size); ! NS_EXTERN void Ns_CacheUnsetValue(Ns_Entry *entry); ! NS_EXTERN void Ns_CacheDeleteEntry(Ns_Entry *entry); ! NS_EXTERN void Ns_CacheFlushEntry(Ns_Entry *entry); ! NS_EXTERN Ns_Entry *Ns_CacheFirstEntry(Ns_Cache *cache, Ns_CacheSearch *search); ! NS_EXTERN Ns_Entry *Ns_CacheNextEntry(Ns_CacheSearch *search); ! NS_EXTERN void Ns_CacheFlush(Ns_Cache *cache); ! NS_EXTERN void Ns_CacheLock(Ns_Cache *cache); ! NS_EXTERN int Ns_CacheTryLock(Ns_Cache *cache); ! NS_EXTERN void Ns_CacheUnlock(Ns_Cache *cache); ! NS_EXTERN int Ns_CacheTimedWait(Ns_Cache *cache, Ns_Time *timePtr); ! NS_EXTERN void Ns_CacheWait(Ns_Cache *cache); ! NS_EXTERN void Ns_CacheSignal(Ns_Cache *cache); ! NS_EXTERN void Ns_CacheBroadcast(Ns_Cache *cache); /* --- 571,682 ---- */ ! NS_EXTERN Ns_Cache * ! Ns_CacheCreate(CONST char *name, int keys, time_t ttl, Ns_Callback *freeProc) ! NS_GNUC_NONNULL(1); ! ! NS_EXTERN Ns_Cache * ! Ns_CacheCreateSz(CONST char *name, int keys, size_t maxSize, Ns_Callback *freeProc) ! NS_GNUC_NONNULL(1); ! ! NS_EXTERN Ns_Cache * ! Ns_CacheCreateEx(CONST char *name, int keys, time_t ttl, size_t maxSize, ! Ns_Callback *freeProc) ! NS_GNUC_NONNULL(1); ! ! NS_EXTERN void ! Ns_CacheDestroy(Ns_Cache *cache) ! NS_GNUC_NONNULL(1); ! ! NS_EXTERN Ns_Entry * ! Ns_CacheFindEntry(Ns_Cache *cache, CONST char *key) ! NS_GNUC_NONNULL(1) NS_GNUC_NONNULL(2); ! ! NS_EXTERN Ns_Entry * ! Ns_CacheCreateEntry(Ns_Cache *cache, CONST char *key, int *newPtr) ! NS_GNUC_NONNULL(1) NS_GNUC_NONNULL(2) NS_GNUC_NONNULL(3); ! ! NS_EXTERN Ns_Entry * ! Ns_CacheWaitCreateEntry(Ns_Cache *cache, CONST char *key, int *newPtr, time_t timeout) ! NS_GNUC_NONNULL(1) NS_GNUC_NONNULL(2) NS_GNUC_NONNULL(3); ! ! NS_EXTERN char * ! Ns_CacheKey(Ns_Entry *entry) ! NS_GNUC_NONNULL(1); ! ! NS_EXTERN void * ! Ns_CacheGetValue(Ns_Entry *entry) ! NS_GNUC_NONNULL(1); ! ! NS_EXTERN size_t ! Ns_CacheGetSize(Ns_Entry *entry) ! NS_GNUC_NONNULL(1); ! ! NS_EXTERN void ! Ns_CacheSetValue(Ns_Entry *entry, void *value) ! NS_GNUC_NONNULL(1) NS_GNUC_NONNULL(2); ! ! NS_EXTERN void ! Ns_CacheSetValueSz(Ns_Entry *entry, void *value, size_t size) ! NS_GNUC_NONNULL(1) NS_GNUC_NONNULL(2); ! ! NS_EXTERN void ! Ns_CacheSetValueExpires(Ns_Entry *entry, void *value, size_t size, time_t ttl) ! NS_GNUC_NONNULL(1); ! ! NS_EXTERN void ! Ns_CacheUnsetValue(Ns_Entry *entry) ! NS_GNUC_NONNULL(1); ! ! NS_EXTERN void ! Ns_CacheDeleteEntry(Ns_Entry *entry) ! NS_GNUC_NONNULL(1); ! ! NS_EXTERN void ! Ns_CacheFlushEntry(Ns_Entry *entry) ! NS_GNUC_NONNULL(1); ! ! NS_EXTERN Ns_Entry * ! Ns_CacheFirstEntry(Ns_Cache *cache, Ns_CacheSearch *search) ! NS_GNUC_NONNULL(1) NS_GNUC_NONNULL(2); ! ! NS_EXTERN Ns_Entry * ! Ns_CacheNextEntry(Ns_CacheSearch *search) ! NS_GNUC_NONNULL(1); ! ! NS_EXTERN int ! Ns_CacheFlush(Ns_Cache *cache) ! NS_GNUC_NONNULL(1); ! ! NS_EXTERN void ! Ns_CacheLock(Ns_Cache *cache) ! NS_GNUC_NONNULL(1); ! ! NS_EXTERN int ! Ns_CacheTryLock(Ns_Cache *cache) ! NS_GNUC_NONNULL(1); ! ! NS_EXTERN void ! Ns_CacheUnlock(Ns_Cache *cache) ! NS_GNUC_NONNULL(1); ! ! NS_EXTERN void ! Ns_CacheWait(Ns_Cache *cache) ! NS_GNUC_NONNULL(1); ! ! NS_EXTERN int ! Ns_CacheTimedWait(Ns_Cache *cache, Ns_Time *timePtr) ! NS_GNUC_NONNULL(1); ! ! NS_EXTERN void ! Ns_CacheSignal(Ns_Cache *cache) ! NS_GNUC_NONNULL(1); ! ! NS_EXTERN void ! Ns_CacheBroadcast(Ns_Cache *cache) ! NS_GNUC_NONNULL(1); ! ! NS_EXTERN void ! Ns_CacheStats(Ns_Cache *cache, Ns_DString *dest) ! NS_GNUC_NONNULL(1) NS_GNUC_NONNULL(2); /* |