From fa80a8ef90d0dce41426904f53438e3564d975b0 Mon Sep 17 00:00:00 2001 From: hno <> Date: Sun, 14 Apr 2002 05:07:47 +0000 Subject: [PATCH] New improved reference based cbdata API, avoiding the need to manual lock/unlock. Including full programmers guide documentation --- configure.in | 12 +- doc/Programming-Guide/prog-guide.sgml | 206 +++++++++++++++++++++++--- src/MemBuf.cc | 28 ++-- src/acl.cc | 49 +++--- src/asn.cc | 7 +- src/auth/basic/auth_basic.cc | 23 ++- src/auth/digest/auth_digest.cc | 13 +- src/auth/ntlm/auth_ntlm.cc | 24 ++- src/cache_cf.cc | 13 +- src/cachemgr.cc | 5 +- src/carp.cc | 7 +- src/cbdata.cc | 165 +++++++++++++-------- src/client_side.cc | 12 +- src/comm.cc | 55 ++++--- src/comm_poll.cc | 18 +-- src/comm_select.cc | 18 +-- src/defines.h | 19 ++- src/delay_pools.cc | 4 +- src/disk.cc | 37 +++-- src/dns_internal.cc | 29 ++-- src/event.cc | 33 ++--- src/forward.cc | 5 +- src/fqdncache.cc | 21 ++- src/fs/aufs/async_io.cc | 46 +++--- src/fs/aufs/store_io_aufs.cc | 31 ++-- src/fs/coss/async_io.cc | 22 +-- src/fs/coss/store_io_coss.cc | 27 ++-- src/fs/diskd/store_io_diskd.cc | 100 ++++++------- src/fs/ufs/store_io_ufs.cc | 33 ++--- src/ftp.cc | 4 +- src/globals.h | 4 +- src/helper.cc | 50 ++++--- src/htcp.cc | 4 +- src/ident.cc | 15 +- src/ipcache.cc | 23 ++- src/mem.cc | 46 +++--- src/neighbors.cc | 14 +- src/net_db.cc | 50 +++---- src/pconn.cc | 14 +- src/peer_digest.cc | 144 +++++++++--------- src/peer_select.cc | 22 +-- src/protos.h | 31 ++-- src/redirect.cc | 13 +- src/squid.h | 28 ++-- src/ssl.cc | 26 ++-- src/store_client.cc | 64 ++++---- src/store_swapin.cc | 11 +- src/store_swapout.cc | 10 +- src/structs.h | 5 +- src/tunnel.cc | 26 ++-- src/urn.cc | 9 +- 51 files changed, 896 insertions(+), 779 deletions(-) diff --git a/configure.in b/configure.in index cdf9aaf301..80de528f71 100644 --- a/configure.in +++ b/configure.in @@ -3,7 +3,7 @@ dnl Configuration input file for Squid dnl dnl Duane Wessels, wessels@nlanr.net, February 1996 (autoconf v2.9) dnl -dnl $Id: configure.in,v 1.265 2002/04/13 16:29:06 hno Exp $ +dnl $Id: configure.in,v 1.266 2002/04/13 23:07:47 hno Exp $ dnl dnl dnl @@ -11,7 +11,7 @@ AC_INIT(src/main.c) AC_CONFIG_AUX_DIR(cfgaux) AM_INIT_AUTOMAKE(squid, 2.6-DEVEL) AM_CONFIG_HEADER(include/autoconf.h) -AC_REVISION($Revision: 1.265 $)dnl +AC_REVISION($Revision: 1.266 $)dnl AC_PREFIX_DEFAULT(/usr/local/squid) AM_MAINTAINER_MODE @@ -218,6 +218,14 @@ AC_ARG_ENABLE(gnuregex, [ --enable-gnuregex Compile GNUregex], [USE_GNUREGEX=$enableval]) +AC_ARG_ENABLE(debug-cbdata, +[ --enable-debug-cbdata Provide some debug information in cbdata], +[ if test "$enableval" = "yes" ; then + echo "cbdata debugging enabled" + AC_DEFINE(CBDATA_DEBUG) + fi +]) + dnl This is a developer only option.. developers know how to set defines dnl dnl AC_ARG_ENABLE(xmalloc-debug, diff --git a/doc/Programming-Guide/prog-guide.sgml b/doc/Programming-Guide/prog-guide.sgml index e156e15187..78973838a0 100644 --- a/doc/Programming-Guide/prog-guide.sgml +++ b/doc/Programming-Guide/prog-guide.sgml @@ -2,7 +2,7 @@
Squid Programmers Guide Squid Developers -$Id: prog-guide.sgml,v 1.48 2002/04/06 08:49:22 adrian Exp $ +$Id: prog-guide.sgml,v 1.49 2002/04/13 23:07:47 hno Exp $ Squid is a WWW Cache application developed by the National Laboratory @@ -2447,13 +2447,13 @@ $|=1; # no buffering, important! while (<>) { chop; ($u,$p) = split; - $ans = &check($u,$p); + $ans = &check($u,$p); print "$ans\n"; } sub check { local($u,$p) = @_; - return 'ERR' unless (defined $p && defined $u); + return 'ERR' unless (defined $p && defined $u); return 'OK' if ('Dirk' eq $u); return 'OK' if ('Sekrit' eq $p); return 'ERR'; @@ -2483,7 +2483,163 @@ sub check {

Squid's extensive use of callback functions makes it very - susceptible to memory access errors. For a blocking operation + susceptible to memory access errors. To address this all callback + functions make use of a construct called "cbdata". This allows + functions doing callbacks to verify that the caller is still + valid before making the callback. + +

+ Note: cbdata is intended for callback data and is tailored specifically + to make callbacks less dangerous leaving as few windows of errors as + possible. It is not suitable or intended as a generic referencecounted + memory allocator. + +API + +CBDATA_TYPE + +

+ + CBDATA_TYPE(datatype); + + +

+ Macro that defines a new cbdata datatype. Similar to a variable + or struct definition. Scope is always local to the file/block + where it is defined and all allocations must be within this scope. + Allocated entries referenced or freed anywhere with no restrictions + on scope. + +CBDATA_GLOBAL_TYPE + +

+ + /* Module header file */ + external CBDATA_GLOBAL_TYPE(datatype); + + /* Module main C file */ + CBDATA_GLOBAL_TYPE(datatype); + + +

+ Defines a global cbdata type that can be referenced anywhere in + the code. + +CBDATA_INIT_TYPE + +

+ + CBDATA_INIT_TYPE(datatype); + /* or */ + CBDATA_INIT_TYPE_FREECB(datatype, FREE *freehandler); + + +

+ Initializes the cbdatatype. Must be called prior to the first use of + cbdataAlloc() for the type. + +

+ The freehandler is called when the last known reference to a + allocated entry goes away. + +cbdataAlloc + +

+ + pointer = cbdataAlloc(datatype); + + +

+ Allocates a new entry of a registered cbdata type. + +cbdataFree + +

+ + cbdataFree(pointer); + + +

+ Frees a entry allocated by cbdataAlloc(). + +

+ Note: If there are active references to the entry then the entry + will be freed with the last reference is removed. However, + cbdataReferenceValid() will return false for those references. + +cbdataReference + +

+ + reference = cbdataReference(pointer); + + +

+ Creates a new reference to a cbdata entry. Used when you need to + store a reference in another structure. The reference can later + be verified for validity by cbdataReferenceValid(). + +

+ Note: The reference variable is a pointer to the entry, in all + aspects identical to the original pointer. But semantically it + is quite different. It is best if the reference is thought of + and handled as a "void *". + +cbdataReferenceDone + +

+ + cbdataReferenceDone(reference); + + +

+ Removes a reference created by cbdataReference(). + +

+ Note: The reference variable will be automatically cleared to NULL. + +cbdataReferenceValid + +

+ + if (cbdataReferenceValid(reference)) { + ... + } + + +

+ cbdataReferenceValid() returns false if a reference is stale (refers to a + entry freed by cbdataFree). + +cbdataReferenceValidDone + +

+ + void *pointer; + bool cbdataReferenceValidDone(reference, &pointer); + + +

+ Removes a reference created by cbdataReference() and checks + it for validity. + +

+ Meant to be used on the last dereference + + + void *cbdata; + ... + if (cbdataReferenceValidDone(reference, &cbdata)) != NULL) + callback(..., cbdata); + + +

+ Note: The reference variable will be automatically cleared to NULL. + +Examples + +

+ For a blocking operation with callback functions, the normal sequence of events is as follows: @@ -2508,40 +2664,54 @@ sub check { operation executes elsewhere, and is freed when the operation completes. The normal sequence of events is: + /* initialization */ type_of_data callback_data; ... callback_data = cbdataAlloc(type_of_data); ... - cbdataLock(callback_data); - fooOperationStart(bar, callback_func, callback_data); + /* calling "foo" */ + fooOperationStart(..., callback_func, callback_data); ... - fooOperationComplete(...); - if (cbdataValid(callback_data)) { - callback_func(callback_data, ....); - cbdataUnlock(callback_data); + /* being destroyed */ cbdataFree(callback_data); + + /* foo */ + void + fooOperationStart(..., callback_func, void *callback_data) + { + void *local_pointer = cbdataReference(callback_data); + .... + } + void + fooOperationComplete(...) + { + void *cbdata; + ... + if (cbdataReferenceValidDone(local_pointer, &cbdata)) + callback_func(...., cbdata); + }

With this scheme, nothing bad happens if callback_data = cbdataAlloc(...); ... - cbdataLock(callback_data); fooOperationStart(bar, callback_func, callback_data); + local_pointer = cbdataReference(callback_data); ... cbdataFree(callback_data); ... fooOperationComplete(...); - if (cbdataValid(callback_data)) { - callback_func(callback_data, ....); - cbdataUnlock(callback_data); + void *cbdata; + if (cbdataReferenceValidDone(local_pointer, cbdata)) + callback_func(cbdata, ....); In this case, when buf); assert(!mb->stolen); /* not frozen */ - ff = memFreeBufFunc((size_t)mb->capacity); - mb->stolen = 1; /* freeze */ + ff = memFreeBufFunc((size_t) mb->capacity); + mb->stolen = 1; /* freeze */ return ff; } @@ -287,26 +287,26 @@ memBufGrow(MemBuf * mb, mb_size_t min_cap) assert(mb->capacity < min_cap); /* determine next capacity */ - if (min_cap > 64*1024) { - new_cap = 64*1024; - while (new_cap < (size_t)min_cap) - new_cap += 64*1024; /* increase in reasonable steps */ + if (min_cap > 64 * 1024) { + new_cap = 64 * 1024; + while (new_cap < (size_t) min_cap) + new_cap += 64 * 1024; /* increase in reasonable steps */ } else { - new_cap = (size_t)min_cap; + new_cap = (size_t) min_cap; } /* last chance to fit before we assert(!overflow) */ - if (new_cap > (size_t)mb->max_capacity) - new_cap = (size_t)mb->max_capacity; + if (new_cap > (size_t) mb->max_capacity) + new_cap = (size_t) mb->max_capacity; - assert(new_cap <= (size_t)mb->max_capacity); /* no overflow */ - assert(new_cap > (size_t)mb->capacity); /* progress */ + assert(new_cap <= (size_t) mb->max_capacity); /* no overflow */ + assert(new_cap > (size_t) mb->capacity); /* progress */ - buf_cap = (size_t)mb->capacity; + buf_cap = (size_t) mb->capacity; mb->buf = memReallocBuf(mb->buf, new_cap, &buf_cap); /* done */ - mb->capacity = (mb_size_t)buf_cap; + mb->capacity = (mb_size_t) buf_cap; } diff --git a/src/acl.cc b/src/acl.cc index c309460cbc..27b1694c92 100644 --- a/src/acl.cc +++ b/src/acl.cc @@ -1,6 +1,6 @@ /* - * $Id: acl.cc,v 1.272 2002/04/11 16:45:28 hno Exp $ + * $Id: acl.cc,v 1.273 2002/04/13 23:07:48 hno Exp $ * * DEBUG: section 28 Access Control * AUTHOR: Duane Wessels @@ -1760,14 +1760,17 @@ aclCheck(aclCheck_t * checklist) const acl_access *A; int match; ipcache_addrs *ia; + /* NOTE: This holds a cbdata reference to the current access_list + * entry, not the whole list. + */ while ((A = checklist->access_list) != NULL) { /* * If the _acl_access is no longer valid (i.e. its been * freed because of a reconfigure), then bail on this * access check. For now, return ACCESS_DENIED. */ - if (!cbdataValid(A)) { - cbdataUnlock(A); + if (!cbdataReferenceValid(A)) { + cbdataReferenceDone(checklist->access_list); break; } debug(28, 3) ("aclCheck: checking '%s'\n", A->cfgline); @@ -1817,15 +1820,14 @@ aclCheck(aclCheck_t * checklist) #if USE_IDENT else if (checklist->state[ACL_IDENT] == ACL_LOOKUP_NEEDED) { debug(28, 3) ("aclCheck: Doing ident lookup\n"); - if (cbdataValid(checklist->conn)) { + if (checklist->conn && cbdataReferenceValid(checklist->conn)) { identStart(&checklist->conn->me, &checklist->conn->peer, aclLookupIdentDone, checklist); checklist->state[ACL_IDENT] = ACL_LOOKUP_PENDING; return; } else { debug(28, 1) ("aclCheck: Can't start ident lookup. No client connection\n"); - cbdataUnlock(checklist->conn); - checklist->conn = NULL; + cbdataReferenceDone(checklist->conn); allow = 0; match = -1; } @@ -1836,18 +1838,17 @@ aclCheck(aclCheck_t * checklist) * is allowed, denied, requires authentication, or we move on to * the next entry. */ - cbdataUnlock(A); if (match) { debug(28, 3) ("aclCheck: match found, returning %d\n", allow); + cbdataReferenceDone(checklist->access_list); /* A */ aclCheckCallback(checklist, allow); return; } - checklist->access_list = A->next; /* - * Lock the next _acl_access entry + * Reference the next _acl_access entry */ - if (A->next) - cbdataLock(A->next); + checklist->access_list = cbdataReference(A->next); + cbdataReferenceDone(A); } debug(28, 3) ("aclCheck: NO match found, returning %d\n", allow != ACCESS_DENIED ? ACCESS_DENIED : ACCESS_ALLOWED); aclCheckCallback(checklist, allow != ACCESS_DENIED ? ACCESS_DENIED : ACCESS_ALLOWED); @@ -1859,16 +1860,15 @@ aclChecklistFree(aclCheck_t * checklist) if (checklist->request) requestUnlink(checklist->request); checklist->request = NULL; - if (checklist->conn) { - cbdataUnlock(checklist->conn); - checklist->conn = NULL; - } + cbdataReferenceDone(checklist->conn); cbdataFree(checklist); } static void aclCheckCallback(aclCheck_t * checklist, allow_t answer) { + PF *callback; + void *cbdata; debug(28, 3) ("aclCheckCallback: answer=%d\n", answer); /* During reconfigure, we can end up not finishing call sequences into the auth code */ if (checklist->auth_user_request) { @@ -1880,11 +1880,10 @@ aclCheckCallback(aclCheck_t * checklist, allow_t answer) checklist->conn->auth_type = AUTH_BROKEN; checklist->auth_user_request = NULL; } - if (cbdataValid(checklist->callback_data)) - checklist->callback(answer, checklist->callback_data); - cbdataUnlock(checklist->callback_data); + callback = checklist->callback; checklist->callback = NULL; - checklist->callback_data = NULL; + if (cbdataReferenceValidDone(checklist->callback_data, &cbdata)) + callback(answer, cbdata); aclChecklistFree(checklist); } @@ -1905,7 +1904,7 @@ aclLookupIdentDone(const char *ident, void *data) * Cache the ident result in the connection, to avoid redoing ident lookup * over and over on persistent connections */ - if (cbdataValid(checklist->conn) && !checklist->conn->rfc931[0]) + if (cbdataReferenceValid(checklist->conn) && !checklist->conn->rfc931[0]) xstrncpy(checklist->conn->rfc931, checklist->rfc931, USER_IDENT_SZ); aclCheck(checklist); } @@ -1970,12 +1969,7 @@ aclChecklistCreate(const acl_access * A, request_t * request, const char *ident) int i; aclCheck_t *checklist; checklist = cbdataAlloc(aclCheck_t); - checklist->access_list = A; - /* - * aclCheck() makes sure checklist->access_list is a valid - * pointer, so lock it. - */ - cbdataLock(A); + checklist->access_list = cbdataReference(A); if (request != NULL) { checklist->request = requestLink(request); checklist->src_addr = request->client_addr; @@ -1996,8 +1990,7 @@ void aclNBCheck(aclCheck_t * checklist, PF * callback, void *callback_data) { checklist->callback = callback; - checklist->callback_data = callback_data; - cbdataLock(callback_data); + checklist->callback_data = cbdataReference(callback_data); aclCheck(checklist); } diff --git a/src/asn.cc b/src/asn.cc index 0462fb0b60..2c82a534af 100644 --- a/src/asn.cc +++ b/src/asn.cc @@ -1,6 +1,6 @@ /* - * $Id: asn.cc,v 1.79 2002/02/26 15:48:13 adrian Exp $ + * $Id: asn.cc,v 1.80 2002/04/13 23:07:49 hno Exp $ * * DEBUG: section 53 AS Number handling * AUTHOR: Duane Wessels, Kostas Anagnostakis @@ -228,7 +228,7 @@ asHandleReply(void *data, char *unused_buf, ssize_t retsize) char *buf = asState->reqbuf; int leftoversz = -1; - debug(53, 3) ("asHandleReply: Called with size=%d\n", (int)retsize); + debug(53, 3) ("asHandleReply: Called with size=%d\n", (int) retsize); debug(53, 3) ("asHandleReply: buffer='%s'\n", buf); /* First figure out whether we should abort the request */ @@ -249,7 +249,6 @@ asHandleReply(void *data, char *unused_buf, ssize_t retsize) asStateFree(asState); return; } - /* * Next, attempt to parse our request * Remembering that the actual buffer size is retsize + reqofs! @@ -291,7 +290,7 @@ asHandleReply(void *data, char *unused_buf, ssize_t retsize) */ asState->offset += retsize; asState->reqofs = leftoversz; - debug(53, 3) ("asState->offset = %ld\n",(long int) asState->offset); + debug(53, 3) ("asState->offset = %ld\n", (long int) asState->offset); if (e->store_status == STORE_PENDING) { debug(53, 3) ("asHandleReply: store_status == STORE_PENDING: %s\n", storeUrl(e)); storeClientCopy(asState->sc, diff --git a/src/auth/basic/auth_basic.cc b/src/auth/basic/auth_basic.cc index 5613592a3e..d78c870cbd 100644 --- a/src/auth/basic/auth_basic.cc +++ b/src/auth/basic/auth_basic.cc @@ -1,5 +1,5 @@ /* - * $Id: auth_basic.cc,v 1.16 2002/04/06 08:49:31 adrian Exp $ + * $Id: auth_basic.cc,v 1.17 2002/04/13 23:07:53 hno Exp $ * * DEBUG: section 29 Authenticator * AUTHOR: Duane Wessels @@ -261,8 +261,8 @@ authenticateBasicHandleReply(void *data, char *reply) auth_user_t *auth_user; basic_data *basic_auth; auth_basic_queue_node *tmpnode; - int valid; char *t = NULL; + void *cbdata; debug(29, 9) ("authenticateBasicHandleReply: {%s}\n", reply ? reply : ""); if (reply) { if ((t = strchr(reply, ' '))) @@ -279,16 +279,13 @@ authenticateBasicHandleReply(void *data, char *reply) else basic_auth->flags.credentials_ok = 3; basic_auth->credentials_checkedtime = squid_curtime; - valid = cbdataValid(r->data); - if (valid) - r->handler(r->data, NULL); - cbdataUnlock(r->data); + if (cbdataReferenceValidDone(r->data, &cbdata)) + r->handler(cbdata, NULL); + cbdataReferenceDone(r->data); while (basic_auth->auth_queue) { tmpnode = basic_auth->auth_queue->next; - valid = cbdataValid(basic_auth->auth_queue->data); - if (valid) - basic_auth->auth_queue->handler(basic_auth->auth_queue->data, NULL); - cbdataUnlock(basic_auth->auth_queue->data); + if (cbdataReferenceValidDone(basic_auth->auth_queue->data, &cbdata)) + basic_auth->auth_queue->handler(cbdata, NULL); xfree(basic_auth->auth_queue); basic_auth->auth_queue = tmpnode; } @@ -584,14 +581,12 @@ authenticateBasicStart(auth_user_request_t * auth_user_request, RH * handler, vo basic_auth->auth_queue = node; node->auth_user_request = auth_user_request; node->handler = handler; - node->data = data; - cbdataLock(data); + node->data = cbdataReference(data); return; } else { r = cbdataAlloc(authenticateStateData); r->handler = handler; - cbdataLock(data); - r->data = data; + r->data = cbdataReference(data); r->auth_user_request = auth_user_request; /* mark the user as haveing verification in progress */ basic_auth->flags.credentials_ok = 2; diff --git a/src/auth/digest/auth_digest.cc b/src/auth/digest/auth_digest.cc index e6e8f6c281..6868d272a0 100644 --- a/src/auth/digest/auth_digest.cc +++ b/src/auth/digest/auth_digest.cc @@ -1,6 +1,6 @@ /* - * $Id: auth_digest.cc,v 1.13 2002/04/06 08:49:37 adrian Exp $ + * $Id: auth_digest.cc,v 1.14 2002/04/13 23:07:54 hno Exp $ * * DEBUG: section 29 Authenticator * AUTHOR: Robert Collins @@ -836,8 +836,8 @@ authenticateDigestHandleReply(void *data, char *reply) auth_user_request_t *auth_user_request; digest_request_h *digest_request; digest_user_h *digest_user; - int valid; char *t = NULL; + void *cbdata; debug(29, 9) ("authenticateDigestHandleReply: {%s}\n", reply ? reply : ""); if (reply) { if ((t = strchr(reply, ' '))) @@ -856,10 +856,8 @@ authenticateDigestHandleReply(void *data, char *reply) CvtBin(reply, digest_user->HA1); digest_user->HA1created = 1; } - valid = cbdataValid(r->data); - if (valid) - r->handler(r->data, NULL); - cbdataUnlock(r->data); + if (cbdataReferenceValidDone(r->data, &cbdata)) + r->handler(cbdata, NULL); authenticateStateFree(r); } @@ -1348,8 +1346,7 @@ authenticateDigestStart(auth_user_request_t * auth_user_request, RH * handler, v } r = cbdataAlloc(authenticateStateData); r->handler = handler; - cbdataLock(data); - r->data = data; + r->data = cbdataReference(data); r->auth_user_request = auth_user_request; snprintf(buf, 8192, "\"%s\":\"%s\"\n", digest_user->username, digest_request->realm); helperSubmit(digestauthenticators, buf, authenticateDigestHandleReply, r); diff --git a/src/auth/ntlm/auth_ntlm.cc b/src/auth/ntlm/auth_ntlm.cc index 25b00317c0..4d7cb4545c 100644 --- a/src/auth/ntlm/auth_ntlm.cc +++ b/src/auth/ntlm/auth_ntlm.cc @@ -1,6 +1,6 @@ /* - * $Id: auth_ntlm.cc,v 1.20 2002/04/06 08:49:39 adrian Exp $ + * $Id: auth_ntlm.cc,v 1.21 2002/04/13 23:07:54 hno Exp $ * * DEBUG: section 29 NTLM Authenticator * AUTHOR: Robert Collins @@ -401,20 +401,18 @@ authenticateNTLMHandleplaceholder(void *data, void *lastserver, char *reply) { authenticateStateData *r = data; stateful_helper_callback_t result = S_HELPER_UNKNOWN; - int valid; /* we should only be called for placeholder requests - which have no reply string */ assert(reply == NULL); assert(r->auth_user_request); /* standard callback stuff */ - valid = cbdataValid(r->data); - if (!valid) { + if (!cbdataReferenceValid(r->data)) { debug(29, 1) ("AuthenticateNTLMHandlePlacheholder: invalid callback data.\n"); return result; } /* call authenticateNTLMStart to retry this request */ debug(29, 9) ("authenticateNTLMHandleplaceholder: calling authenticateNTLMStart\n"); authenticateNTLMStart(r->auth_user_request, r->handler, r->data); - cbdataUnlock(r->data); + cbdataReferenceDone(r->data); authenticateStateFree(r); return result; } @@ -424,7 +422,6 @@ authenticateNTLMHandleReply(void *data, void *lastserver, char *reply) { authenticateStateData *r = data; ntlm_helper_state_t *helperstate; - int valid; stateful_helper_callback_t result = S_HELPER_UNKNOWN; char *t = NULL; auth_user_request_t *auth_user_request; @@ -432,10 +429,9 @@ authenticateNTLMHandleReply(void *data, void *lastserver, char *reply) ntlm_user_t *ntlm_user; ntlm_request_t *ntlm_request; debug(29, 9) ("authenticateNTLMHandleReply: Helper: '%p' {%s}\n", lastserver, reply ? reply : ""); - valid = cbdataValid(r->data); - if (!valid) { + if (!cbdataReferenceValid(r->data)) { debug(29, 1) ("AuthenticateNTLMHandleReply: invalid callback data. Releasing helper '%p'.\n", lastserver); - cbdataUnlock(r->data); + cbdataReferenceDone(r->data); authenticateStateFree(r); debug(29, 9) ("NTLM HandleReply, telling stateful helper : %d\n", S_HELPER_RELEASE); return S_HELPER_RELEASE; @@ -567,7 +563,7 @@ authenticateNTLMHandleReply(void *data, void *lastserver, char *reply) * a different one. Our auth state stays the same */ authenticateNTLMStart(auth_user_request, r->handler, r->data); /* don't call the callback */ - cbdataUnlock(r->data); + cbdataReferenceDone(r->data); authenticateStateFree(r); debug(29, 9) ("NTLM HandleReply, telling stateful helper : %d\n", result); return result; @@ -599,7 +595,7 @@ authenticateNTLMHandleReply(void *data, void *lastserver, char *reply) ntlm_request->authserver = NULL; } r->handler(r->data, NULL); - cbdataUnlock(r->data); + cbdataReferenceDone(r->data); authenticateStateFree(r); debug(29, 9) ("NTLM HandleReply, telling stateful helper : %d\n", result); return result; @@ -727,8 +723,7 @@ authenticateNTLMStart(auth_user_request_t * auth_user_request, RH * handler, voi /* No server, or server with invalid challenge */ r = cbdataAlloc(authenticateStateData); r->handler = handler; - cbdataLock(data); - r->data = data; + r->data = cbdataReference(data); r->auth_user_request = auth_user_request; if (server == NULL) { helperStatefulSubmit(ntlmauthenticators, NULL, authenticateNTLMHandleplaceholder, r, NULL); @@ -755,8 +750,7 @@ authenticateNTLMStart(auth_user_request_t * auth_user_request, RH * handler, voi case AUTHENTICATE_STATE_RESPONSE: r = cbdataAlloc(authenticateStateData); r->handler = handler; - cbdataLock(data); - r->data = data; + r->data = cbdataReference(data); r->auth_user_request = auth_user_request; snprintf(buf, 8192, "KK %s\n", sent_string); /* getting rid of deferred request status */ diff --git a/src/cache_cf.cc b/src/cache_cf.cc index baa3000c85..86d2bc9803 100644 --- a/src/cache_cf.cc +++ b/src/cache_cf.cc @@ -1,6 +1,6 @@ /* - * $Id: cache_cf.cc,v 1.406 2002/04/13 22:30:53 hno Exp $ + * $Id: cache_cf.cc,v 1.407 2002/04/13 23:07:49 hno Exp $ * * DEBUG: section 3 Configuration File Parsing * AUTHOR: Harvest Derived @@ -1510,8 +1510,11 @@ parse_peer(peer ** head) p->test_fd = -1; #if USE_CACHE_DIGESTS if (!p->options.no_digest) { - p->digest = peerDigestCreate(p); - cbdataLock(p->digest); /* so we know when/if digest disappears */ + /* XXX This looks odd.. who has the original pointer + * then? + */ + PeerDigest *pd = peerDigestCreate(p); + p->digest = cbdataReference(pd); } #endif while (*head != NULL) @@ -1528,9 +1531,7 @@ free_peer(peer ** P) while ((p = *P) != NULL) { *P = p->next; #if USE_CACHE_DIGESTS - if (p->digest) - cbdataUnlock(p->digest); - p->digest = NULL; + cbdataReferenceDone(p->digest); #endif cbdataFree(p); } diff --git a/src/cachemgr.cc b/src/cachemgr.cc index b8e3b5dcc3..672fa89eee 100644 --- a/src/cachemgr.cc +++ b/src/cachemgr.cc @@ -1,6 +1,6 @@ /* - * $Id: cachemgr.cc,v 1.93 2002/04/11 17:04:02 hno Exp $ + * $Id: cachemgr.cc,v 1.94 2002/04/13 23:07:49 hno Exp $ * * DEBUG: section 0 CGI Cache Manager * AUTHOR: Duane Wessels @@ -537,8 +537,7 @@ process_request(cachemgr_request * req) if ((hp = gethostbyname(req->hostname)) != NULL) { assert(hp->h_length <= sizeof(S.sin_addr.s_addr)); xmemcpy(&S.sin_addr.s_addr, hp->h_addr, hp->h_length); - } - else if (safe_inet_addr(req->hostname, &S.sin_addr)) + } else if (safe_inet_addr(req->hostname, &S.sin_addr)) (void) 0; else { snprintf(buf, 1024, "Unknown host: %s\n", req->hostname); diff --git a/src/carp.cc b/src/carp.cc index d0bb384edd..b08fc63d9e 100644 --- a/src/carp.cc +++ b/src/carp.cc @@ -1,6 +1,6 @@ /* - * $Id: carp.cc,v 1.18 2002/04/13 16:24:50 hno Exp $ + * $Id: carp.cc,v 1.19 2002/04/13 23:07:49 hno Exp $ * * DEBUG: section 39 Cache Array Routing Protocol * AUTHOR: Henrik Nordstrom @@ -63,7 +63,7 @@ carpInit(void) char *t; /* Clean up */ for (k = 0; k < n_carp_peers; k++) { - cbdataUnlock(carp_peers[k]); + cbdataReferenceDone(carp_peers[k]); } safe_free(carp_peers); n_carp_peers = 0; @@ -97,8 +97,7 @@ carpInit(void) if (floor(p->carp.load_factor * 1000.0) == 0.0) p->carp.load_factor = 0.0; /* add it to our list of peers */ - *P++ = p; - cbdataLock(p); + *P++ = cbdataReference(p); } /* Sort our list on weight */ qsort(carp_peers, n_carp_peers, sizeof(*carp_peers), peerSortWeight); diff --git a/src/cbdata.cc b/src/cbdata.cc index dd993d6722..a4cff9c515 100644 --- a/src/cbdata.cc +++ b/src/cbdata.cc @@ -1,6 +1,6 @@ /* - * $Id: cbdata.cc,v 1.42 2001/10/17 19:43:39 hno Exp $ + * $Id: cbdata.cc,v 1.43 2002/04/13 23:07:49 hno Exp $ * * DEBUG: section 45 Callback Data Registry * ORIGINAL AUTHOR: Duane Wessels @@ -42,41 +42,25 @@ * pointers, lock them just before registering the callback function, * validate them before issuing the callback, and then free them * when finished. - * - * In terms of time, the sequence goes something like this: - * - * foo = cbdataAlloc(sizeof(foo),NULL); - * ... - * some_blocking_operation(..., callback_func, foo); - * cbdataLock(foo); - * ... - * some_blocking_operation_completes() - * if (cbdataValid(foo)) - * callback_func(..., foo) - * cbdataUnlock(foo); - * ... - * cbdataFree(foo); - * - * The nice thing is that, we do not need to require that Unlock - * occurs before Free. If the Free happens first, then the - * callback data is marked invalid and the callback will never - * be made. When we Unlock and the lock count reaches zero, - * we free the memory if it is marked invalid. */ #include "squid.h" static int cbdataCount = 0; +#if CBDATA_DEBUG +dlink_list cbdataEntries; +#endif typedef struct _cbdata { int valid; int locks; int type; #if CBDATA_DEBUG + dlink_node link; const char *file; int line; #endif - void *y; /* cookie used while debugging */ + long y; /* cookie used while debugging */ union { void *pointer; double double_float; @@ -93,9 +77,11 @@ struct { int cbdata_types = 0; #define OFFSET_OF(type, member) ((int)(char *)&((type *)0L)->member) +#define CBDATA_COOKIE 0xDEADBEEF +#define CBDATA_CHECK(c) assert(c->y == ((long)c ^ CBDATA_COOKIE)) -void -cbdataInitType(cbdata_type type, const char *name, int size, FREE * free_func) +static void +cbdataInternalInitType(cbdata_type type, const char *name, int size, FREE * free_func) { char *label; if (type >= cbdata_types) { @@ -114,12 +100,12 @@ cbdataInitType(cbdata_type type, const char *name, int size, FREE * free_func) } cbdata_type -cbdataAddType(cbdata_type type, const char *name, int size, FREE * free_func) +cbdataInternalAddType(cbdata_type type, const char *name, int size, FREE * free_func) { if (type) return type; type = cbdata_types; - cbdataInitType(type, name, size, free_func); + cbdataInternalInitType(type, name, size, free_func); return type; } @@ -130,8 +116,11 @@ cbdataInit(void) cachemgrRegister("cbdata", "Callback Data Registry Contents", cbdataDump, 0, 1); -#define CREATE_CBDATA(type) cbdataInitType(CBDATA_##type, #type, sizeof(type), NULL) -#define CREATE_CBDATA_FREE(type, free_func) cbdataInitType(CBDATA_##type, #type, sizeof(type), free_func) +#define CREATE_CBDATA(type) cbdataInternalInitType(CBDATA_##type, #type, sizeof(type), NULL) +#define CREATE_CBDATA_FREE(type, free_func) cbdataInternalInitType(CBDATA_##type, #type, sizeof(type), free_func) + /* XXX + * most of these should be moved out to their respective module. + */ CREATE_CBDATA(acl_access); CREATE_CBDATA(aclCheck_t); CREATE_CBDATA(clientHttpRequest); @@ -169,20 +158,31 @@ cbdataInternalAlloc(cbdata_type type) p->file = file; p->line = line; #endif - p->y = p; + p->y = (long) p ^ CBDATA_COOKIE; cbdataCount++; +#if CBDATA_DEBUG + dlinkAdd(p, &p->link, &cbdataEntries); +#endif return (void *) &p->data; } void * +#if CBDATA_DEBUG +cbdataInternalFreeDbg(void *p, const char *file, int line) +#else cbdataInternalFree(void *p) +#endif { cbdata *c; FREE *free_func; +#if CBDATA_DEBUG + debug(45, 3) ("cbdataFree: %p %s:%d\n", p, file, line); +#else debug(45, 3) ("cbdataFree: %p\n", p); +#endif c = (cbdata *) (((char *) p) - OFFSET_OF(cbdata, data)); - assert(c->y == c); + CBDATA_CHECK(c); c->valid = 0; if (c->locks) { debug(45, 3) ("cbdataFree: %p has %d locks, not freeing\n", @@ -191,6 +191,9 @@ cbdataInternalFree(void *p) } cbdataCount--; debug(45, 3) ("cbdataFree: Freeing %p\n", p); +#if CBDATA_DEBUG + dlinkDelete(&c->link, &cbdataEntries); +#endif free_func = cbdata_index[c->type].free_func; if (free_func) free_func((void *) p); @@ -198,44 +201,31 @@ cbdataInternalFree(void *p) return NULL; } -int -cbdataLocked(const void *p) -{ - cbdata *c; - assert(p); - c = (cbdata *) (((char *) p) - OFFSET_OF(cbdata, data)); - assert(c->y == c); - debug(45, 3) ("cbdataLocked: %p = %d\n", p, c->locks); - assert(c != NULL); - return c->locks; -} - void #if CBDATA_DEBUG -cbdataLockDbg(const void *p, const char *file, int line) +cbdataInternalLockDbg(const void *p, const char *file, int line) #else -cbdataLock(const void *p) +cbdataInternalLock(const void *p) #endif { cbdata *c; if (p == NULL) return; c = (cbdata *) (((char *) p) - OFFSET_OF(cbdata, data)); - assert(c->y == c); - debug(45, 3) ("cbdataLock: %p\n", p); - assert(c != NULL); - c->locks++; #if CBDATA_DEBUG - c->file = file; - c->line = line; + debug(45, 3) ("cbdataLock: %p=%d %s:%d\n", p, c ? c->locks + 1 : -1, file, line); +#else + debug(45, 3) ("cbdataLock: %p=%d\n", p, c ? c->locks + 1 : -1); #endif + CBDATA_CHECK(c); + c->locks++; } void #if CBDATA_DEBUG -cbdataUnlockDbg(const void *p, const char *file, int line) +cbdataInternalUnlockDbg(const void *p, const char *file, int line) #else -cbdataUnlock(const void *p) +cbdataInternalUnlock(const void *p) #endif { cbdata *c; @@ -243,19 +233,22 @@ cbdataUnlock(const void *p) if (p == NULL) return; c = (cbdata *) (((char *) p) - OFFSET_OF(cbdata, data)); - assert(c->y == c); - debug(45, 3) ("cbdataUnlock: %p\n", p); +#if CBDATA_DEBUG + debug(45, 3) ("cbdataUnlock: %p=%d %s:%d\n", p, c ? c->locks - 1 : -1, file, line); +#else + debug(45, 3) ("cbdataUnlock: %p=%d\n", p, c ? c->locks - 1 : -1); +#endif + CBDATA_CHECK(c); assert(c != NULL); assert(c->locks > 0); c->locks--; -#if CBDATA_DEBUG - c->file = file; - c->line = line; -#endif if (c->valid || c->locks) return; cbdataCount--; debug(45, 3) ("cbdataUnlock: Freeing %p\n", p); +#if CBDATA_DEBUG + dlinkDelete(&c->link, &cbdataEntries); +#endif free_func = cbdata_index[c->type].free_func; if (free_func) free_func((void *) p); @@ -263,21 +256,69 @@ cbdataUnlock(const void *p) } int -cbdataValid(const void *p) +cbdataReferenceValid(const void *p) { cbdata *c; if (p == NULL) return 1; /* A NULL pointer cannot become invalid */ - debug(45, 3) ("cbdataValid: %p\n", p); + debug(45, 3) ("cbdataReferenceValid: %p\n", p); c = (cbdata *) (((char *) p) - OFFSET_OF(cbdata, data)); - assert(c->y == c); + CBDATA_CHECK(c); assert(c->locks > 0); return c->valid; } +int +#if CBDATA_DEBUG +cbdataInternalReferenceDoneValidDbg(void **pp, void **tp, const char *file, int line) +#else +cbdataInternalReferenceDoneValid(void **pp, void **tp) +#endif +{ + void *p = (void *) *pp; + int valid = cbdataReferenceValid(p); + *pp = NULL; +#if CBDATA_DEBUG + cbdataInternalUnlockDbg(p, file, line); +#else + cbdataInternalUnlock(p); +#endif + if (valid) { + *tp = p; + return 1; + } else { + *tp = NULL; + return 0; + } +} + + static void cbdataDump(StoreEntry * sentry) { +#if CBDATA_DEBUG + dlink_node *n; + cbdata *p; + int i; +#endif storeAppendPrintf(sentry, "%d cbdata entries\n", cbdataCount); - storeAppendPrintf(sentry, "see also memory pools section\n"); +#if CBDATA_DEBUG + storeAppendPrintf(sentry, "Pointer\tType\tLocks\tAllocated by\n"); + for (n = cbdataEntries.head; n; n = n->next) { + p = n->data; + storeAppendPrintf(sentry, "%c%p\t%d\t%d\t%20s:%-5d\n", p->valid ? ' ' : '!', &p->data, p->type, p->locks, p->file, p->line); + } + storeAppendPrintf(sentry, "\n"); + storeAppendPrintf(sentry, "types\tsize\tallocated\ttotal\n"); + for (i = 1; i < cbdata_types; i++) { + MemPool *pool = cbdata_index[i].pool; + if (pool) { + int obj_size = pool->obj_size - OFFSET_OF(cbdata, data); + storeAppendPrintf(sentry, "%s\t%d\t%d\t%d\n", pool->label + 7, obj_size, pool->meter.inuse.level, obj_size * pool->meter.inuse.level); + } + } +#else + storeAppendPrintf(sentry, "detailed allocation information only available when compiled with CBDATA_DEBUG\n"); +#endif + storeAppendPrintf(sentry, "\nsee also \"Memory utilization\" for detailed per type statistics\n"); } diff --git a/src/client_side.cc b/src/client_side.cc index 07f13c82b7..66cbd4e699 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -1,6 +1,6 @@ /* - * $Id: client_side.cc,v 1.572 2002/04/13 15:30:10 hno Exp $ + * $Id: client_side.cc,v 1.573 2002/04/13 23:07:49 hno Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -168,8 +168,7 @@ clientAclChecklistCreate(const acl_access * acl, const clientHttpRequest * http) * place to store the ident result on persistent connections... */ /* connection oriented auth also needs these two lines for it's operation. */ - ch->conn = conn; - cbdataLock(ch->conn); + ch->conn = cbdataReference(conn); /* unreferenced in acl.c */ return ch; } @@ -2526,13 +2525,6 @@ clientReadRequest(int fd, void *data) for (H = &conn->chr; *H; H = &(*H)->next); *H = http; conn->nrequests++; - /* - * I wanted to lock 'http' here since its callback data for - * clientLifetimeTimeout(), but there's no logical place to - * cbdataUnlock if the timeout never happens. Maybe its safe - * enough to assume that if the FD is open, and the timeout - * triggers, that 'http' is valid. - */ commSetTimeout(fd, Config.Timeout.lifetime, clientLifetimeTimeout, http); if (parser_return_code < 0) { debug(33, 1) ("clientReadRequest: FD %d Invalid Request\n", fd); diff --git a/src/comm.cc b/src/comm.cc index 4cda13a42b..a9f09a4dfe 100644 --- a/src/comm.cc +++ b/src/comm.cc @@ -1,6 +1,6 @@ /* - * $Id: comm.cc,v 1.328 2002/04/01 06:02:15 wessels Exp $ + * $Id: comm.cc,v 1.329 2002/04/13 23:07:49 hno Exp $ * * DEBUG: section 5 Socket Functions * AUTHOR: Harvest Derived @@ -82,7 +82,7 @@ CommWriteStateCallbackAndFree(int fd, int code) { CommWriteStateData *CommWriteState = fd_table[fd].rwstate; CWCB *callback = NULL; - void *data; + void *cbdata; fd_table[fd].rwstate = NULL; if (CommWriteState == NULL) return; @@ -94,11 +94,9 @@ CommWriteStateCallbackAndFree(int fd, int code) free_func(free_buf); } callback = CommWriteState->handler; - data = CommWriteState->handler_data; CommWriteState->handler = NULL; - if (callback && cbdataValid(data)) - callback(fd, CommWriteState->buf, CommWriteState->offset, code, data); - cbdataUnlock(data); + if (callback && cbdataReferenceValidDone(CommWriteState->handler_data, &cbdata)) + callback(fd, CommWriteState->buf, CommWriteState->offset, code, cbdata); memPoolFree(comm_write_pool, CommWriteState); } @@ -269,8 +267,7 @@ commConnectStart(int fd, const char *host, u_short port, CNCB * callback, void * cs->host = xstrdup(host); cs->port = port; cs->callback = callback; - cs->data = data; - cbdataLock(cs->data); + cs->data = cbdataReference(data); comm_add_close_handler(fd, commConnectFree, cs); cs->locks++; ipcache_nbgethostbyname(host, commConnectDnsHandle, cs); @@ -304,16 +301,15 @@ static void commConnectCallback(ConnectStateData * cs, int status) { CNCB *callback = cs->callback; - void *data = cs->data; + void *cbdata = cs->data; int fd = cs->fd; comm_remove_close_handler(fd, commConnectFree, cs); cs->callback = NULL; cs->data = NULL; commSetTimeout(fd, -1, NULL, NULL); commConnectFree(fd, cs); - if (cbdataValid(data)) - callback(fd, status, data); - cbdataUnlock(data); + if (cbdataReferenceValid(cbdata)) + callback(fd, status, cbdata); } static void @@ -321,8 +317,7 @@ commConnectFree(int fd, void *data) { ConnectStateData *cs = data; debug(5, 3) ("commConnectFree: FD %d\n", fd); - if (cs->data) - cbdataUnlock(cs->data); + cbdataReferenceDone(cs->data); safe_free(cs->host); cbdataFree(cs); } @@ -333,7 +328,7 @@ commResetFD(ConnectStateData * cs) { int fd2; fde *F; - if (!cbdataValid(cs->data)) + if (!cbdataReferenceValid(cs->data)) return 0; statCounter.syscalls.sock.sockets++; fd2 = socket(AF_INET, SOCK_STREAM, 0); @@ -443,15 +438,16 @@ commSetTimeout(int fd, int timeout, PF * handler, void *data) assert(fd < Squid_MaxFD); F = &fd_table[fd]; assert(F->flags.open); + cbdataReferenceDone(F->timeout_data); + F->timeout_handler = NULL; if (timeout < 0) { F->timeout_handler = NULL; - F->timeout_data = NULL; return F->timeout = 0; } assert(handler || F->timeout_handler); if (handler || data) { F->timeout_handler = handler; - F->timeout_data = data; + F->timeout_data = cbdataReference(data); } return F->timeout = squid_curtime + (time_t) timeout; } @@ -568,9 +564,9 @@ commCallCloseHandlers(int fd) while ((ch = F->close_handler) != NULL) { F->close_handler = ch->next; debug(5, 5) ("commCallCloseHandlers: ch->handler=%p\n", ch->handler); - if (cbdataValid(ch->data)) + if (cbdataReferenceValid(ch->data)) ch->handler(fd, ch->data); - cbdataUnlock(ch->data); + cbdataReferenceDone(ch->data); memPoolFree(conn_close_pool, ch); /* AAA */ } } @@ -650,6 +646,7 @@ comm_close(int fd) if (F->ssl) ssl_shutdown_method(fd); #endif + commSetTimeout(fd, -1, NULL, NULL); CommWriteStateCallbackAndFree(fd, COMM_ERR_CLOSING); commCallCloseHandlers(fd); if (F->uses) /* assume persistent connect count */ @@ -708,10 +705,9 @@ comm_add_close_handler(int fd, PF * handler, void *data) for (c = fd_table[fd].close_handler; c; c = c->next) assert(c->handler != handler || c->data != data); new->handler = handler; - new->data = data; + new->data = cbdataReference(data); new->next = fd_table[fd].close_handler; fd_table[fd].close_handler = new; - cbdataLock(data); } void @@ -731,9 +727,8 @@ comm_remove_close_handler(int fd, PF * handler, void *data) last->next = p->next; else fd_table[fd].close_handler = p->next; - cbdataUnlock(p->data); - memPoolFree(conn_close_pool, p); /* AAA */ - + cbdataReferenceDone(p->data); + memPoolFree(conn_close_pool, p); } static void @@ -929,9 +924,8 @@ comm_write(int fd, const char *buf, int size, CWCB * handler, void *handler_data state->size = size; state->offset = 0; state->handler = handler; - state->handler_data = handler_data; + state->handler_data = cbdataReference(handler_data); state->free_func = free_func; - cbdataLock(handler_data); commSetSelect(fd, COMM_SELECT_WRITE, commHandleWrite, state, 0); } @@ -972,7 +966,6 @@ commCloseAllSockets(void) { int fd; fde *F = NULL; - PF *callback; for (fd = 0; fd <= Biggest_FD; fd++) { F = &fd_table[fd]; if (!F->flags.open) @@ -982,11 +975,13 @@ commCloseAllSockets(void) if (F->flags.ipc) /* don't close inter-process sockets */ continue; if (F->timeout_handler) { + PF *callback = F->timeout_handler; + void *cbdata = NULL; + F->timeout_handler = NULL; debug(5, 5) ("commCloseAllSockets: FD %d: Calling timeout handler\n", fd); - callback = F->timeout_handler; - F->timeout_handler = NULL; - callback(fd, F->timeout_data); + if (cbdataReferenceValidDone(F->timeout_data, &cbdata)) + callback(fd, cbdata); } else { debug(5, 5) ("commCloseAllSockets: FD %d: calling comm_close()\n", fd); comm_close(fd); diff --git a/src/comm_poll.cc b/src/comm_poll.cc index f4713a0011..0833a1cae2 100644 --- a/src/comm_poll.cc +++ b/src/comm_poll.cc @@ -1,6 +1,6 @@ /* - * $Id: comm_poll.cc,v 1.1 2001/12/24 15:33:42 adrian Exp $ + * $Id: comm_poll.cc,v 1.2 2002/04/13 23:07:49 hno Exp $ * * DEBUG: section 5 Socket Functions * @@ -126,24 +126,24 @@ static int incoming_http_interval = 16 << INCOMING_FACTOR; void commSetSelect(int fd, unsigned int type, PF * handler, void *client_data, - time_t timeout) + time_t timeout) { fde *F = &fd_table[fd]; assert(fd >= 0); assert(F->flags.open); debug(5, 5) ("commSetSelect: FD %d type %d\n", fd, type); if (type & COMM_SELECT_READ) { - F->read_handler = handler; - F->read_data = client_data; - commUpdateReadBits(fd, handler); + F->read_handler = handler; + F->read_data = client_data; + commUpdateReadBits(fd, handler); } if (type & COMM_SELECT_WRITE) { - F->write_handler = handler; - F->write_data = client_data; - commUpdateWriteBits(fd, handler); + F->write_handler = handler; + F->write_data = client_data; + commUpdateWriteBits(fd, handler); } if (timeout) - F->timeout = squid_curtime + timeout; + F->timeout = squid_curtime + timeout; } static int diff --git a/src/comm_select.cc b/src/comm_select.cc index 447d8f97fc..e369a6a924 100644 --- a/src/comm_select.cc +++ b/src/comm_select.cc @@ -1,6 +1,6 @@ /* - * $Id: comm_select.cc,v 1.54 2001/12/24 15:33:42 adrian Exp $ + * $Id: comm_select.cc,v 1.55 2002/04/13 23:07:49 hno Exp $ * * DEBUG: section 5 Socket Functions * @@ -128,24 +128,24 @@ static int incoming_http_interval = 16 << INCOMING_FACTOR; void commSetSelect(int fd, unsigned int type, PF * handler, void *client_data, - time_t timeout) + time_t timeout) { fde *F = &fd_table[fd]; assert(fd >= 0); assert(F->flags.open); debug(5, 5) ("commSetSelect: FD %d type %d\n", fd, type); if (type & COMM_SELECT_READ) { - F->read_handler = handler; - F->read_data = client_data; - commUpdateReadBits(fd, handler); + F->read_handler = handler; + F->read_data = client_data; + commUpdateReadBits(fd, handler); } if (type & COMM_SELECT_WRITE) { - F->write_handler = handler; - F->write_data = client_data; - commUpdateWriteBits(fd, handler); + F->write_handler = handler; + F->write_data = client_data; + commUpdateWriteBits(fd, handler); } if (timeout) - F->timeout = squid_curtime + timeout; + F->timeout = squid_curtime + timeout; } diff --git a/src/defines.h b/src/defines.h index 4b33a5d07c..0792a151ad 100644 --- a/src/defines.h +++ b/src/defines.h @@ -1,6 +1,6 @@ /* - * $Id: defines.h,v 1.101 2002/04/06 08:49:27 adrian Exp $ + * $Id: defines.h,v 1.102 2002/04/13 23:07:49 hno Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -287,12 +287,23 @@ #endif /* cbdata macros */ +#if CBDATA_DEBUG +#define cbdataAlloc(type) ((type *)cbdataInternalAllocDbg(CBDATA_##type,__FILE__,__LINE__)) +#define cbdataFree(var) do {if (var) {cbdataInternalFreeDbg(var,__FILE__,__LINE__); var = NULL;}} while(0) +#define cbdataInternalLock(a) cbdataInternalLockDbg(a,__FILE__,__LINE__) +#define cbdataInternalUnlock(a) cbdataInternalUnlockDbg(a,__FILE__,__LINE__) +#define cbdataReferenceValidDone(var, ptr) cbdataInternalReferenceDoneValidDbg((void **)&(var), (ptr), __FILE__,__LINE__) +#else #define cbdataAlloc(type) ((type *)cbdataInternalAlloc(CBDATA_##type)) -#define cbdataFree(var) (var = (var != NULL ? cbdataInternalFree(var): NULL)) +#define cbdataFree(var) do {if (var) {cbdataInternalFree(var); var = NULL;}} while(0) +#define cbdataReferenceValidDone(var, ptr) cbdataInternalReferenceDoneValid((void **)&(var), (ptr)) +#endif +#define cbdataReference(var) (cbdataInternalLock(var), var) +#define cbdataReferenceDone(var) do {if (var) {cbdataInternalUnlock(var); var = NULL;}} while(0) #define CBDATA_TYPE(type) static cbdata_type CBDATA_##type = 0 #define CBDATA_GLOBAL_TYPE(type) cbdata_type CBDATA_##type -#define CBDATA_INIT_TYPE(type) (CBDATA_##type ? 0 : (CBDATA_##type = cbdataAddType(CBDATA_##type, #type, sizeof(type), NULL))) -#define CBDATA_INIT_TYPE_FREECB(type, free_func) (CBDATA_##type ? 0 : (CBDATA_##type = cbdataAddType(CBDATA_##type, #type, sizeof(type), free_func))) +#define CBDATA_INIT_TYPE(type) (CBDATA_##type ? 0 : (CBDATA_##type = cbdataInternalAddType(CBDATA_##type, #type, sizeof(type), NULL))) +#define CBDATA_INIT_TYPE_FREECB(type, free_func) (CBDATA_##type ? 0 : (CBDATA_##type = cbdataInternalAddType(CBDATA_##type, #type, sizeof(type), free_func))) #ifndef O_TEXT #define O_TEXT 0 diff --git a/src/delay_pools.cc b/src/delay_pools.cc index d3bdd7198c..1808207d6a 100644 --- a/src/delay_pools.cc +++ b/src/delay_pools.cc @@ -1,6 +1,6 @@ /* - * $Id: delay_pools.cc,v 1.20 2002/01/06 00:44:13 hno Exp $ + * $Id: delay_pools.cc,v 1.21 2002/04/13 23:07:50 hno Exp $ * * DEBUG: section 77 Delay Pools * AUTHOR: David Luyer @@ -648,8 +648,6 @@ delayMostBytesWanted(const MemObject * mem, int max) dlink_node *node; for (node = mem->clients.head; node; node = node->next) { sc = (store_client *) node->data; - if (sc->callback_data == NULL) /* open slot */ - continue; if (sc->type != STORE_MEM_CLIENT) continue; i = delayBytesWanted(sc->delay_id, i, max); diff --git a/src/disk.cc b/src/disk.cc index 4421e2ab5f..d874050646 100644 --- a/src/disk.cc +++ b/src/disk.cc @@ -1,6 +1,6 @@ /* - * $Id: disk.cc,v 1.157 2001/08/16 00:16:16 hno Exp $ + * $Id: disk.cc,v 1.158 2002/04/13 23:07:50 hno Exp $ * * DEBUG: section 6 Disk I/O Routines * AUTHOR: Harvest Derived @@ -179,7 +179,6 @@ diskHandleWrite(int fd, void *notused) struct _fde_disk *fdd = &F->disk; dwrite_q *q = fdd->write_q; int status = DISK_OK; - int do_callback; int do_close; if (NULL == q) return; @@ -259,27 +258,22 @@ diskHandleWrite(int fd, void *notused) } else { /* another block is queued */ diskCombineWrites(fdd); - cbdataLock(fdd->wrt_handle_data); commSetSelect(fd, COMM_SELECT_WRITE, diskHandleWrite, NULL, 0); F->flags.write_daemon = 1; } do_close = F->flags.close_request; if (fdd->wrt_handle) { - if (fdd->wrt_handle_data == NULL) - do_callback = 1; - else if (cbdataValid(fdd->wrt_handle_data)) - do_callback = 1; - else - do_callback = 0; - if (fdd->wrt_handle_data != NULL) - cbdataUnlock(fdd->wrt_handle_data); - if (do_callback) { - fdd->wrt_handle(fd, status, len, fdd->wrt_handle_data); + DWCB *callback = fdd->wrt_handle; + void *cbdata; + fdd->wrt_handle = NULL; + if (cbdataReferenceValidDone(fdd->wrt_handle_data, &cbdata)) { + callback(fd, status, len, cbdata); /* * NOTE, this callback can close the FD, so we must * not touch 'F', 'fdd', etc. after this. */ return; + /* XXX But what about close_request??? */ } } if (do_close) @@ -311,8 +305,13 @@ file_write(int fd, wq->buf_offset = 0; wq->next = NULL; wq->free_func = free_func; - F->disk.wrt_handle = handle; - F->disk.wrt_handle_data = handle_data; + if (!F->disk.wrt_handle_data) { + F->disk.wrt_handle = handle; + F->disk.wrt_handle_data = cbdataReference(handle_data); + } else { + /* Detect if there is multiple concurrent users of this fd.. we only support one callback */ + assert(F->disk.wrt_handle_data == handle_data && F->disk.wrt_handle == handle); + } /* add to queue */ if (F->disk.write_q == NULL) { /* empty queue */ @@ -322,7 +321,6 @@ file_write(int fd, F->disk.write_q_tail = wq; } if (!F->flags.write_daemon) { - cbdataLock(F->disk.wrt_handle_data); diskHandleWrite(fd, NULL); } } @@ -377,9 +375,9 @@ diskHandleRead(int fd, void *data) } else if (len == 0) { rc = DISK_EOF; } - if (cbdataValid(ctrl_dat->client_data)) + if (cbdataReferenceValid(ctrl_dat->client_data)) ctrl_dat->handler(fd, ctrl_dat->buf, len, rc, ctrl_dat->client_data); - cbdataUnlock(ctrl_dat->client_data); + cbdataReferenceDone(ctrl_dat->client_data); memFree(ctrl_dat, MEM_DREAD_CTRL); } @@ -400,7 +398,6 @@ file_read(int fd, char *buf, int req_len, off_t offset, DRCB * handler, void *cl ctrl_dat->buf = buf; ctrl_dat->end_of_file = 0; ctrl_dat->handler = handler; - ctrl_dat->client_data = client_data; - cbdataLock(client_data); + ctrl_dat->client_data = cbdataReference(client_data); diskHandleRead(fd, ctrl_dat); } diff --git a/src/dns_internal.cc b/src/dns_internal.cc index bdd897698e..d19adeafa9 100644 --- a/src/dns_internal.cc +++ b/src/dns_internal.cc @@ -1,6 +1,6 @@ /* - * $Id: dns_internal.cc,v 1.45 2001/11/17 11:09:24 hno Exp $ + * $Id: dns_internal.cc,v 1.46 2002/04/13 23:07:50 hno Exp $ * * DEBUG: section 78 DNS lookups; interacts with lib/rfc1035.c * AUTHOR: Duane Wessels @@ -440,10 +440,11 @@ static void idnsGrokReply(const char *buf, size_t sz) { int n; - int valid; rfc1035_rr *answers = NULL; unsigned short rid = 0xFFFF; idns_query *q; + IDNSCB *callback; + void *cbdata; n = rfc1035AnswersUnpack(buf, sz, &answers, @@ -477,10 +478,10 @@ idnsGrokReply(const char *buf, size_t sz) return; } } - valid = cbdataValid(q->callback_data); - cbdataUnlock(q->callback_data); - if (valid) - q->callback(q->callback_data, answers, n); + callback = q->callback; + q->callback = NULL; + if (cbdataReferenceValidDone(q->callback_data, &cbdata)) + callback(cbdata, answers, n); rfc1035RRDestroy(answers, n); memFree(q, MEM_IDNS_QUERY); } @@ -579,13 +580,15 @@ idnsCheckQueue(void *unused) if (tvSubDsec(q->start_t, current_time) < Config.Timeout.idns_query) { idnsSendQuery(q); } else { - int v = cbdataValid(q->callback_data); + IDNSCB *callback; + void *cbdata; debug(78, 2) ("idnsCheckQueue: ID %x: giving up after %d tries and %5.1f seconds\n", (int) q->id, q->nsends, tvSubDsec(q->start_t, current_time)); - cbdataUnlock(q->callback_data); - if (v) - q->callback(q->callback_data, NULL, 0); + callback = q->callback; + q->callback = NULL; + if (cbdataReferenceValidDone(q->callback_data, &cbdata)) + callback(cbdata, NULL, 0); memFree(q, MEM_IDNS_QUERY); } } @@ -689,8 +692,7 @@ idnsALookup(const char *name, IDNSCB * callback, void *data) debug(78, 3) ("idnsALookup: buf is %d bytes for %s, id = %#hx\n", (int) q->sz, name, q->id); q->callback = callback; - q->callback_data = data; - cbdataLock(q->callback_data); + q->callback_data = cbdataReference(data); q->start_t = current_time; idnsSendQuery(q); } @@ -704,8 +706,7 @@ idnsPTRLookup(const struct in_addr addr, IDNSCB * callback, void *data) debug(78, 3) ("idnsPTRLookup: buf is %d bytes for %s, id = %#hx\n", (int) q->sz, inet_ntoa(addr), q->id); q->callback = callback; - q->callback_data = data; - cbdataLock(q->callback_data); + q->callback_data = cbdataReference(data); q->start_t = current_time; idnsSendQuery(q); } diff --git a/src/event.cc b/src/event.cc index 50d59bf188..424ce460bc 100644 --- a/src/event.cc +++ b/src/event.cc @@ -1,6 +1,6 @@ /* - * $Id: event.cc,v 1.31 2001/01/12 00:37:17 wessels Exp $ + * $Id: event.cc,v 1.32 2002/04/13 23:07:50 hno Exp $ * * DEBUG: section 41 Event Processing * AUTHOR: Henrik Nordstrom @@ -57,13 +57,11 @@ eventAdd(const char *name, EVH * func, void *arg, double when, int weight) struct ev_entry *event = memAllocate(MEM_EVENT); struct ev_entry **E; event->func = func; - event->arg = arg; + event->arg = cbdataReference(arg); event->name = name; event->when = current_dtime + when; event->weight = weight; event->id = run_id; - if (NULL != arg) - cbdataLock(arg); debug(41, 7) ("eventAdd: Adding '%s', in %f seconds\n", name, when); /* Insert after the last event with the same or earlier time */ for (E = &tasks; *E; E = &(*E)->next) { @@ -100,8 +98,7 @@ eventDelete(EVH * func, void *arg) if (event->arg != arg) continue; *E = event->next; - if (NULL != event->arg) - cbdataUnlock(event->arg); + cbdataReferenceDone(event->arg); memFree(event, MEM_EVENT); return; } @@ -112,8 +109,6 @@ void eventRun(void) { struct ev_entry *event = NULL; - EVH *func; - void *arg; int weight = 0; if (NULL == tasks) return; @@ -122,29 +117,24 @@ eventRun(void) run_id++; debug(41, 5) ("eventRun: RUN ID %d\n", run_id); while ((event = tasks)) { - int valid = 1; + EVH *callback; + void *cbdata; if (event->when > current_dtime) break; if (event->id == run_id) /* was added during this run */ break; if (weight) break; - func = event->func; - arg = event->arg; - event->func = NULL; - event->arg = NULL; tasks = event->next; - if (NULL != arg) { - valid = cbdataValid(arg); - cbdataUnlock(arg); - } - if (valid) { + callback = event->func; + event->func = NULL; + if (cbdataReferenceValidDone(event->arg, &cbdata)) { weight += event->weight; /* XXX assumes ->name is static memory! */ last_event_ran = event->name; debug(41, 5) ("eventRun: Running '%s', id %d\n", event->name, event->id); - func(arg); + callback(cbdata); } memFree(event, MEM_EVENT); } @@ -181,7 +171,7 @@ eventDump(StoreEntry * sentry) while (e != NULL) { storeAppendPrintf(sentry, "%s\t%f seconds\t%d\t%s\n", e->name, e->when - current_dtime, e->weight, - e->arg ? cbdataValid(e->arg) ? "yes" : "no" : "N/A"); + e->arg ? cbdataReferenceValid(e->arg) ? "yes" : "no" : "N/A"); e = e->next; } } @@ -192,8 +182,7 @@ eventFreeMemory(void) struct ev_entry *event; while ((event = tasks)) { tasks = event->next; - if (NULL != event->arg) - cbdataUnlock(event->arg); + cbdataReferenceDone(event->arg); memFree(event, MEM_EVENT); } tasks = NULL; diff --git a/src/forward.cc b/src/forward.cc index f5e8c9fd8e..43e7a67485 100644 --- a/src/forward.cc +++ b/src/forward.cc @@ -1,6 +1,6 @@ /* - * $Id: forward.cc,v 1.83 2002/02/26 08:13:07 hno Exp $ + * $Id: forward.cc,v 1.84 2002/04/13 23:07:50 hno Exp $ * * DEBUG: section 17 Request Forwarding * AUTHOR: Duane Wessels @@ -72,8 +72,7 @@ fwdStateServerPeer(FwdState * fwdState) static void fwdServerFree(FwdServer * fs) { - if (fs->peer) - cbdataUnlock(fs->peer); + cbdataReferenceDone(fs->peer); memFree(fs, MEM_FWD_SERVER); } diff --git a/src/fqdncache.cc b/src/fqdncache.cc index e8d30a0f5e..088b02866c 100644 --- a/src/fqdncache.cc +++ b/src/fqdncache.cc @@ -1,6 +1,6 @@ /* - * $Id: fqdncache.cc,v 1.149 2001/10/24 06:16:16 hno Exp $ + * $Id: fqdncache.cc,v 1.150 2002/04/13 23:07:50 hno Exp $ * * DEBUG: section 35 FQDN Cache * AUTHOR: Harvest Derived @@ -204,19 +204,18 @@ fqdncacheAddEntry(fqdncache_entry * f) static void fqdncacheCallback(fqdncache_entry * f) { - FQDNH *handler = f->handler; - void *handlerData = f->handlerData; + FQDNH *callback; + void *cbdata; f->lastref = squid_curtime; - if (NULL == handler) + if (!f->handler) return; fqdncacheLockEntry(f); + callback = f->handler; f->handler = NULL; - f->handlerData = NULL; - if (cbdataValid(handlerData)) { + if (cbdataReferenceValidDone(f->handlerData, &cbdata)) { dns_error_message = f->error_message; - handler(f->flags.negcached ? NULL : f->names[0], handlerData); + callback(f->flags.negcached ? NULL : f->names[0], cbdata); } - cbdataUnlock(handlerData); fqdncacheUnlockEntry(f); } @@ -374,8 +373,7 @@ fqdncache_nbgethostbyaddr(struct in_addr addr, FQDNH * handler, void *handlerDat else FqdncacheStats.hits++; f->handler = handler; - f->handlerData = handlerData; - cbdataLock(handlerData); + f->handlerData = cbdataReference(handlerData); fqdncacheCallback(f); return; } @@ -384,8 +382,7 @@ fqdncache_nbgethostbyaddr(struct in_addr addr, FQDNH * handler, void *handlerDat FqdncacheStats.misses++; f = fqdncacheCreateEntry(name); f->handler = handler; - f->handlerData = handlerData; - cbdataLock(handlerData); + f->handlerData = cbdataReference(handlerData); f->request_time = current_time; c = cbdataAlloc(generic_cbdata); c->data = f; diff --git a/src/fs/aufs/async_io.cc b/src/fs/aufs/async_io.cc index 57aa3406eb..f47b5131d3 100644 --- a/src/fs/aufs/async_io.cc +++ b/src/fs/aufs/async_io.cc @@ -1,6 +1,6 @@ /* - * $Id: async_io.cc,v 1.12 2002/04/06 15:08:05 hno Exp $ + * $Id: async_io.cc,v 1.13 2002/04/13 23:07:55 hno Exp $ * * DEBUG: section 32 Asynchronous Disk I/O * AUTHOR: Pete Bentley @@ -116,9 +116,8 @@ aioOpen(const char *path, int oflag, mode_t mode, AIOCB * callback, void *callba ctrlp = memPoolAlloc(squidaio_ctrl_pool); ctrlp->fd = -2; ctrlp->done_handler = callback; - ctrlp->done_handler_data = callback_data; + ctrlp->done_handler_data = cbdataReference(callback_data); ctrlp->operation = _AIO_OPEN; - cbdataLock(callback_data); ctrlp->result.data = ctrlp; squidaio_open(path, oflag, mode, &ctrlp->result); dlinkAdd(ctrlp, &ctrlp->node, &used_list); @@ -148,8 +147,6 @@ void aioCancel(int fd) { squidaio_ctrl_t *curr; - AIOCB *done_handler; - void *their_data; dlink_node *m, *next; assert(initialised); @@ -162,14 +159,13 @@ aioCancel(int fd) squidaio_cancel(&curr->result); - if ((done_handler = curr->done_handler)) { - their_data = curr->done_handler_data; + if (curr->done_handler) { + AIOCB *callback = curr->done_handler; + void *cbdata; curr->done_handler = NULL; - curr->done_handler_data = NULL; debug(32, 2) ("this be aioCancel\n"); - if (cbdataValid(their_data)) - done_handler(fd, their_data, -2, -2); - cbdataUnlock(their_data); + if (cbdataReferenceValidDone(curr->done_handler_data, &cbdata)) + callback(fd, cbdata, -2, -2); } dlinkDelete(m, &used_list); memPoolFree(squidaio_ctrl_pool, curr); @@ -188,7 +184,7 @@ aioWrite(int fd, int offset, char *bufp, int len, AIOCB * callback, void *callba ctrlp = memPoolAlloc(squidaio_ctrl_pool); ctrlp->fd = fd; ctrlp->done_handler = callback; - ctrlp->done_handler_data = callback_data; + ctrlp->done_handler_data = cbdataReference(callback_data); ctrlp->operation = _AIO_WRITE; ctrlp->bufp = bufp; ctrlp->free_func = free_func; @@ -198,7 +194,6 @@ aioWrite(int fd, int offset, char *bufp, int len, AIOCB * callback, void *callba seekmode = SEEK_END; offset = 0; } - cbdataLock(callback_data); ctrlp->result.data = ctrlp; squidaio_write(fd, bufp, len, offset, seekmode, &ctrlp->result); dlinkAdd(ctrlp, &ctrlp->node, &used_list); @@ -216,7 +211,7 @@ aioRead(int fd, int offset, char *bufp, int len, AIOCB * callback, void *callbac ctrlp = memPoolAlloc(squidaio_ctrl_pool); ctrlp->fd = fd; ctrlp->done_handler = callback; - ctrlp->done_handler_data = callback_data; + ctrlp->done_handler_data = cbdataReference(callback_data); ctrlp->operation = _AIO_READ; if (offset >= 0) seekmode = SEEK_SET; @@ -224,7 +219,6 @@ aioRead(int fd, int offset, char *bufp, int len, AIOCB * callback, void *callbac seekmode = SEEK_CUR; offset = 0; } - cbdataLock(callback_data); ctrlp->result.data = ctrlp; squidaio_read(fd, bufp, len, offset, seekmode, &ctrlp->result); dlinkAdd(ctrlp, &ctrlp->node, &used_list); @@ -241,9 +235,8 @@ aioStat(char *path, struct stat *sb, AIOCB * callback, void *callback_data) ctrlp = memPoolAlloc(squidaio_ctrl_pool); ctrlp->fd = -2; ctrlp->done_handler = callback; - ctrlp->done_handler_data = callback_data; + ctrlp->done_handler_data = cbdataReference(callback_data); ctrlp->operation = _AIO_STAT; - cbdataLock(callback_data); ctrlp->result.data = ctrlp; squidaio_stat(path, sb, &ctrlp->result); dlinkAdd(ctrlp, &ctrlp->node, &used_list); @@ -259,9 +252,8 @@ aioUnlink(const char *path, AIOCB * callback, void *callback_data) ctrlp = memPoolAlloc(squidaio_ctrl_pool); ctrlp->fd = -2; ctrlp->done_handler = callback; - ctrlp->done_handler_data = callback_data; + ctrlp->done_handler_data = cbdataReference(callback_data); ctrlp->operation = _AIO_UNLINK; - cbdataLock(callback_data); ctrlp->result.data = ctrlp; squidaio_unlink(path, &ctrlp->result); dlinkAdd(ctrlp, &ctrlp->node, &used_list); @@ -276,9 +268,8 @@ aioTruncate(const char *path, off_t length, AIOCB * callback, void *callback_dat ctrlp = memPoolAlloc(squidaio_ctrl_pool); ctrlp->fd = -2; ctrlp->done_handler = callback; - ctrlp->done_handler_data = callback_data; + ctrlp->done_handler_data = cbdataReference(callback_data); ctrlp->operation = _AIO_TRUNCATE; - cbdataLock(callback_data); ctrlp->result.data = ctrlp; squidaio_truncate(path, length, &ctrlp->result); dlinkAdd(ctrlp, &ctrlp->node, &used_list); @@ -290,8 +281,6 @@ aioCheckCallbacks(SwapDir * SD) { squidaio_result_t *resultp; squidaio_ctrl_t *ctrlp; - AIOCB *done_handler; - void *their_data; int retval = 0; assert(initialised); @@ -303,16 +292,15 @@ aioCheckCallbacks(SwapDir * SD) if (ctrlp == NULL) continue; /* XXX Should not happen */ dlinkDelete(&ctrlp->node, &used_list); - if ((done_handler = ctrlp->done_handler)) { - their_data = ctrlp->done_handler_data; + if (ctrlp->done_handler) { + AIOCB *callback = ctrlp->done_handler; + void *cbdata; ctrlp->done_handler = NULL; - ctrlp->done_handler_data = NULL; - if (cbdataValid(their_data)) { + if (cbdataReferenceValidDone(ctrlp->done_handler_data, &cbdata)) { retval = 1; /* Return that we've actually done some work */ - done_handler(ctrlp->fd, their_data, + callback(ctrlp->fd, cbdata, ctrlp->result.aio_return, ctrlp->result.aio_errno); } - cbdataUnlock(their_data); } /* free data if requested to aioWrite() */ if (ctrlp->free_func) diff --git a/src/fs/aufs/store_io_aufs.cc b/src/fs/aufs/store_io_aufs.cc index afd65a0858..308e92efde 100644 --- a/src/fs/aufs/store_io_aufs.cc +++ b/src/fs/aufs/store_io_aufs.cc @@ -62,9 +62,8 @@ storeAufsOpen(SwapDir * SD, StoreEntry * e, STFNCB * file_callback, sio->swap_dirn = SD->index; sio->mode = O_RDONLY; sio->callback = callback; - sio->callback_data = callback_data; + sio->callback_data = cbdataReference(callback_data); sio->e = e; - cbdataLock(callback_data); Opening_FD++; #if ASYNC_OPEN aioOpen(path, O_RDONLY | O_BINARY, 0644, storeAufsOpenDone, sio); @@ -116,9 +115,8 @@ storeAufsCreate(SwapDir * SD, StoreEntry * e, STFNCB * file_callback, STIOCB * c sio->swap_dirn = dirn; sio->mode = O_WRONLY | O_BINARY; sio->callback = callback; - sio->callback_data = callback_data; + sio->callback_data = cbdataReference(callback_data); sio->e = (StoreEntry *) e; - cbdataLock(callback_data); Opening_FD++; #if ASYNC_CREATE aioOpen(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644, storeAufsOpenDone, sio); @@ -172,9 +170,8 @@ storeAufsRead(SwapDir * SD, storeIOState * sio, char *buf, size_t size, off_t of return; } sio->read.callback = callback; - sio->read.callback_data = callback_data; + sio->read.callback_data = cbdataReference(callback_data); aiostate->read_buf = buf; - cbdataLock(callback_data); debug(78, 3) ("storeAufsRead: dirno %d, fileno %08X, FD %d\n", sio->swap_dirn, sio->swap_filen, aiostate->fd); sio->offset = offset; @@ -306,7 +303,7 @@ storeAufsReadDone(int fd, int errflag, size_t len, void *my_data) storeIOState *sio = my_data; squidaiostate_t *aiostate = (squidaiostate_t *) sio->fsstate; STRCB *callback = sio->read.callback; - void *their_data = sio->read.callback_data; + void *cbdata; ssize_t rlen; debug(78, 3) ("storeAufsReadDone: dirno %d, fileno %08X, FD %d, len %d\n", sio->swap_dirn, sio->swap_filen, fd, len); @@ -331,12 +328,9 @@ storeAufsReadDone(int fd, int errflag, size_t len, void *my_data) errflag = DISK_OK; /* EOF is signalled by len == 0, not errors... */ #endif assert(callback); - assert(their_data); sio->read.callback = NULL; - sio->read.callback_data = NULL; - if (cbdataValid(their_data)) - callback(their_data, aiostate->read_buf, rlen); - cbdataUnlock(their_data); + if (cbdataReferenceValidDone(sio->read.callback_data, &cbdata)) + callback(cbdata, aiostate->read_buf, rlen); aiostate->flags.inreaddone = 0; if (aiostate->flags.close_request) storeAufsIOCallback(sio, errflag); @@ -394,18 +388,17 @@ static void storeAufsIOCallback(storeIOState * sio, int errflag) { STIOCB *callback = sio->callback; - void *their_data = sio->callback_data; squidaiostate_t *aiostate = (squidaiostate_t *) sio->fsstate; int fd = aiostate->fd; debug(78, 3) ("storeAufsIOCallback: errflag=%d\n", errflag); - sio->callback = NULL; - sio->callback_data = NULL; debug(78, 3) ("%s:%d\n", __FILE__, __LINE__); - if (callback) - if (NULL == their_data || cbdataValid(their_data)) - callback(their_data, errflag, sio); + if (callback) { + void *cbdata; + sio->callback = NULL; + if (cbdataReferenceValidDone(sio->callback_data, &cbdata)) + callback(cbdata, errflag, sio); + } debug(78, 3) ("%s:%d\n", __FILE__, __LINE__); - cbdataUnlock(their_data); aiostate->fd = -1; cbdataFree(sio); if (fd < 0) diff --git a/src/fs/coss/async_io.cc b/src/fs/coss/async_io.cc index 0c130d8644..1d42aa80a9 100644 --- a/src/fs/coss/async_io.cc +++ b/src/fs/coss/async_io.cc @@ -11,7 +11,7 @@ * supports are read/write, and since COSS works on a single file * per storedir it should work just fine. * - * $Id: async_io.cc,v 1.7 2001/08/24 13:48:31 hno Exp $ + * $Id: async_io.cc,v 1.8 2002/04/13 23:07:56 hno Exp $ */ #include "squid.h" @@ -75,7 +75,7 @@ a_file_read(async_queue_t * q, int fd, void *buf, int req_len, off_t offset, qe = &q->aq_queue[slot]; qe->aq_e_state = AQ_ENTRY_USED; qe->aq_e_callback.read = callback; - qe->aq_e_callback_data = data; + qe->aq_e_callback_data = cbdataReference(data); qe->aq_e_type = AQ_ENTRY_READ; qe->aq_e_free = NULL; qe->aq_e_buf = buf; @@ -89,9 +89,6 @@ a_file_read(async_queue_t * q, int fd, void *buf, int req_len, off_t offset, /* Account */ q->aq_numpending++; - /* Lock */ - cbdataLock(data); - /* Initiate aio */ if (aio_read(&qe->aq_e_aiocb) < 0) { debug(1, 1) ("Aiee! aio_read() returned error (%d)!\n", errno); @@ -122,7 +119,7 @@ a_file_write(async_queue_t * q, int fd, off_t offset, void *buf, int len, qe = &q->aq_queue[slot]; qe->aq_e_state = AQ_ENTRY_USED; qe->aq_e_callback.write = callback; - qe->aq_e_callback_data = data; + qe->aq_e_callback_data = cbdataReference(data); qe->aq_e_type = AQ_ENTRY_WRITE; qe->aq_e_free = freefunc; qe->aq_e_buf = buf; @@ -136,9 +133,6 @@ a_file_write(async_queue_t * q, int fd, off_t offset, void *buf, int len, /* Account */ q->aq_numpending++; - /* Lock */ - cbdataLock(data); - /* Initiate aio */ if (aio_write(&qe->aq_e_aiocb) < 0) { debug(1, 1) ("Aiee! aio_read() returned error (%d)!\n", errno); @@ -164,7 +158,7 @@ a_file_callback(async_queue_t * q) DRCB *rc; DWCB *wc; FREE *freefunc; - void *callback_data; + void *cbdata; void *buf; int fd; async_queue_entry_t *aqe; @@ -186,7 +180,6 @@ a_file_callback(async_queue_t * q) retval = aio_return(&aqe->aq_e_aiocb); /* Get the callback parameters */ - callback_data = aqe->aq_e_callback_data; freefunc = aqe->aq_e_free; rc = aqe->aq_e_callback.read; wc = aqe->aq_e_callback.write; @@ -200,13 +193,12 @@ a_file_callback(async_queue_t * q) q->aq_numpending--; /* Callback */ - if (cbdataValid(callback_data)) { + if (cbdataReferenceValidDone(aqe->aq_e_callback_data, &cbdata)) { if (type == AQ_ENTRY_READ) - rc(fd, buf, retval, reterr, callback_data); + rc(fd, buf, retval, reterr, cbdata); if (type == AQ_ENTRY_WRITE) - wc(fd, reterr, retval, callback_data); + wc(fd, reterr, retval, cbdata); } - cbdataUnlock(callback_data); if (type == AQ_ENTRY_WRITE && freefunc) freefunc(buf); } diff --git a/src/fs/coss/store_io_coss.cc b/src/fs/coss/store_io_coss.cc index 04bceb1cbe..81e0d0d277 100644 --- a/src/fs/coss/store_io_coss.cc +++ b/src/fs/coss/store_io_coss.cc @@ -1,6 +1,6 @@ /* - * $Id: store_io_coss.cc,v 1.13 2001/10/24 07:45:37 hno Exp $ + * $Id: store_io_coss.cc,v 1.14 2002/04/13 23:07:56 hno Exp $ * * DEBUG: section 81 Storage Manager COSS Interface * AUTHOR: Eric Stern @@ -163,8 +163,7 @@ storeCossCreate(SwapDir * SD, StoreEntry * e, STFNCB * file_callback, STIOCB * c sio->callback = callback; sio->file_callback = file_callback; - sio->callback_data = callback_data; - cbdataLock(callback_data); + sio->callback_data = cbdataReference(callback_data); sio->e = (StoreEntry *) e; cstate->flags.writing = 0; @@ -202,8 +201,7 @@ storeCossOpen(SwapDir * SD, StoreEntry * e, STFNCB * file_callback, sio->mode = O_RDONLY; sio->callback = callback; sio->file_callback = file_callback; - sio->callback_data = callback_data; - cbdataLock(callback_data); + sio->callback_data = cbdataReference(callback_data); sio->st_size = e->swap_file_sz; sio->e = e; @@ -281,7 +279,7 @@ storeCossRead(SwapDir * SD, storeIOState * sio, char *buf, size_t size, off_t of assert(sio->read.callback == NULL); assert(sio->read.callback_data == NULL); sio->read.callback = callback; - sio->read.callback_data = callback_data; + sio->read.callback_data = cbdataReference(callback_data); debug(81, 3) ("storeCossRead: offset %ld\n", (long int) offset); sio->offset = offset; cstate->flags.reading = 1; @@ -341,7 +339,7 @@ storeCossReadDone(int fd, const char *buf, int len, int errflag, void *my_data) storeIOState *sio = my_data; char *p; STRCB *callback = sio->read.callback; - void *their_data = sio->read.callback_data; + void *cbdata; SwapDir *SD = INDEXSD(sio->swap_dirn); CossState *cstate = (CossState *) sio->fsstate; size_t rlen; @@ -365,23 +363,22 @@ storeCossReadDone(int fd, const char *buf, int len, int errflag, void *my_data) rlen = (size_t) cstate->requestlen; } assert(callback); - assert(their_data); sio->read.callback = NULL; - sio->read.callback_data = NULL; - if (cbdataValid(their_data)) - callback(their_data, cstate->requestbuf, rlen); + if (cbdataReferenceValidDone(sio->read.callback_data, &cbdata)) + callback(cbdata, cstate->requestbuf, rlen); } static void storeCossIOCallback(storeIOState * sio, int errflag) { CossState *cstate = (CossState *) sio->fsstate; + STIOCB *callback = sio->callback; + void *cbdata; debug(81, 3) ("storeCossIOCallback: errflag=%d\n", errflag); xfree(cstate->readbuffer); - if (cbdataValid(sio->callback_data)) - sio->callback(sio->callback_data, errflag, sio); - cbdataUnlock(sio->callback_data); - sio->callback_data = NULL; + sio->callback = NULL; + if (cbdataReferenceValidDone(sio->callback_data, &cbdata)) + callback(cbdata, errflag, sio); cbdataFree(sio); } diff --git a/src/fs/diskd/store_io_diskd.cc b/src/fs/diskd/store_io_diskd.cc index e6710e9fb8..7b21e13cb7 100644 --- a/src/fs/diskd/store_io_diskd.cc +++ b/src/fs/diskd/store_io_diskd.cc @@ -1,6 +1,6 @@ /* - * $Id: store_io_diskd.cc,v 1.22 2001/05/30 17:40:26 wessels Exp $ + * $Id: store_io_diskd.cc,v 1.23 2002/04/13 23:07:56 hno Exp $ * * DEBUG: section 81 Squid-side DISKD I/O functions. * AUTHOR: Duane Wessels @@ -78,9 +78,8 @@ storeDiskdOpen(SwapDir * SD, StoreEntry * e, STFNCB * file_callback, sio->swap_dirn = SD->index; sio->mode = O_RDONLY; sio->callback = callback; - sio->callback_data = callback_data; + sio->callback_data = cbdataReference(callback_data); sio->e = e; - cbdataLock(callback_data); diskdstate->flags.writing = 0; diskdstate->flags.reading = 0; @@ -99,7 +98,7 @@ storeDiskdOpen(SwapDir * SD, StoreEntry * e, STFNCB * file_callback, if (x < 0) { debug(50, 1) ("storeDiskdSend OPEN: %s\n", xstrerror()); storeDiskdShmPut(SD, shm_offset); - cbdataUnlock(sio->callback_data); + cbdataReferenceDone(sio->callback_data); cbdataFree(sio); return NULL; } @@ -137,9 +136,8 @@ storeDiskdCreate(SwapDir * SD, StoreEntry * e, STFNCB * file_callback, sio->swap_dirn = SD->index; sio->mode = O_WRONLY | O_CREAT | O_TRUNC; sio->callback = callback; - sio->callback_data = callback_data; + sio->callback_data = cbdataReference(callback_data); sio->e = e; - cbdataLock(callback_data); diskdstate->flags.writing = 0; diskdstate->flags.reading = 0; @@ -158,7 +156,7 @@ storeDiskdCreate(SwapDir * SD, StoreEntry * e, STFNCB * file_callback, if (x < 0) { debug(50, 1) ("storeDiskdSend OPEN: %s\n", xstrerror()); storeDiskdShmPut(SD, shm_offset); - cbdataUnlock(sio->callback_data); + cbdataReferenceDone(sio->callback_data); cbdataFree(sio); return NULL; } @@ -199,7 +197,7 @@ storeDiskdRead(SwapDir * SD, storeIOState * sio, char *buf, size_t size, off_t o diskdstate_t *diskdstate = sio->fsstate; debug(81, 3) ("storeDiskdRead: dirno %d, fileno %08X\n", sio->swap_dirn, sio->swap_filen); assert(!diskdstate->flags.close_request); - if (!cbdataValid(sio)) + if (!cbdataReferenceValid(sio)) return; if (diskdstate->flags.reading) { debug(81, 1) ("storeDiskdRead: already reading!\n"); @@ -208,9 +206,8 @@ storeDiskdRead(SwapDir * SD, storeIOState * sio, char *buf, size_t size, off_t o assert(sio->read.callback == NULL); assert(sio->read.callback_data == NULL); sio->read.callback = callback; - sio->read.callback_data = callback_data; + sio->read.callback_data = cbdataReference(callback_data); diskdstate->read_buf = buf; /* the one passed from above */ - cbdataLock(sio->read.callback_data); sio->offset = offset; diskdstate->flags.reading = 1; rbuf = storeDiskdShmGet(SD, &shm_offset); @@ -239,7 +236,7 @@ storeDiskdWrite(SwapDir * SD, storeIOState * sio, char *buf, size_t size, off_t diskdstate_t *diskdstate = sio->fsstate; debug(81, 3) ("storeDiskdWrite: dirno %d, fileno %08X\n", SD->index, sio->swap_filen); assert(!diskdstate->flags.close_request); - if (!cbdataValid(sio)) { + if (!cbdataReferenceValid(sio)) { free_func(buf); return; } @@ -338,18 +335,15 @@ storeDiskdReadDone(diomsg * M) { storeIOState *sio = M->callback_data; STRCB *callback = sio->read.callback; + void *cbdata; SwapDir *sd = INDEXSD(sio->swap_dirn); diskdstate_t *diskdstate = sio->fsstate; diskdinfo_t *diskdinfo = sd->fsdata; - void *their_data = sio->read.callback_data; char *their_buf = diskdstate->read_buf; char *sbuf; size_t len; - int valid; statCounter.syscalls.disk.reads++; diskdstate->flags.reading = 0; - valid = cbdataValid(sio->read.callback_data); - cbdataUnlock(sio->read.callback_data); debug(81, 3) ("storeDiskdReadDone: dirno %d, fileno %08x status %d\n", sio->swap_dirn, sio->swap_filen, M->status); if (M->status < 0) { @@ -362,10 +356,8 @@ storeDiskdReadDone(diomsg * M) len = M->status; sio->offset += len; assert(callback); - assert(their_data); sio->read.callback = NULL; - sio->read.callback_data = NULL; - if (valid) { + if (cbdataReferenceValidDone(sio->read.callback_data, &cbdata)) { assert(!diskdstate->flags.close_request); /* * Only copy the data if the callback is still valid, @@ -374,7 +366,7 @@ storeDiskdReadDone(diomsg * M) * -- adrian */ xmemcpy(their_buf, sbuf, len); /* yucky copy */ - callback(their_data, their_buf, len); + callback(cbdata, their_buf, len); } } @@ -411,10 +403,28 @@ storeDiskdUnlinkDone(diomsg * M) void storeDiskdHandle(diomsg * M) { - int valid = M->callback_data ? cbdataValid(M->callback_data) : 1; - if (M->callback_data) - cbdataUnlock(M->callback_data); - if (!valid) { + if (cbdataReferenceValid(M->callback_data)) { + switch (M->mtype) { + case _MQD_OPEN: + storeDiskdOpenDone(M); + break; + case _MQD_CLOSE: + storeDiskdCloseDone(M); + break; + case _MQD_READ: + storeDiskdReadDone(M); + break; + case _MQD_WRITE: + storeDiskdWriteDone(M); + break; + case _MQD_UNLINK: + storeDiskdUnlinkDone(M); + break; + default: + assert(0); + break; + } + } else { debug(81, 3) ("storeDiskdHandle: Invalid callback_data %p\n", M->callback_data); /* @@ -423,41 +433,26 @@ storeDiskdHandle(diomsg * M) * callback_data gets unlocked! */ if (_MQD_READ == M->mtype) { + /* XXX This cannot be the correct approach. This + * is most likely the wrong place for this. It should + * be done before the sio becomes invalid, not here. + */ storeIOState *sio = M->callback_data; - cbdataUnlock(sio->read.callback_data); + cbdataReferenceDone(sio->read.callback_data); } - return; - } - switch (M->mtype) { - case _MQD_OPEN: - storeDiskdOpenDone(M); - break; - case _MQD_CLOSE: - storeDiskdCloseDone(M); - break; - case _MQD_READ: - storeDiskdReadDone(M); - break; - case _MQD_WRITE: - storeDiskdWriteDone(M); - break; - case _MQD_UNLINK: - storeDiskdUnlinkDone(M); - break; - default: - assert(0); - break; } + cbdataReferenceDone(M->callback_data); } static void storeDiskdIOCallback(storeIOState * sio, int errflag) { - int valid = cbdataValid(sio->callback_data); + void *cbdata; + STIOCB *callback = sio->callback; debug(81, 3) ("storeUfsIOCallback: errflag=%d\n", errflag); - cbdataUnlock(sio->callback_data); - if (valid) - sio->callback(sio->callback_data, errflag, sio); + sio->callback = NULL; + if (cbdataReferenceValidDone(sio->callback_data, &cbdata)) + callback(cbdata, errflag, sio); cbdataFree(sio); } @@ -471,15 +466,13 @@ storeDiskdSend(int mtype, SwapDir * sd, int id, storeIOState * sio, int size, in static int seq_no = 0; diskdinfo_t *diskdinfo = sd->fsdata; M.mtype = mtype; - M.callback_data = sio; + M.callback_data = cbdataReference(sio); M.size = size; M.offset = offset; M.status = -1; M.shm_offset = (int) shm_offset; M.id = id; M.seq_no = ++seq_no; - if (M.callback_data) - cbdataLock(M.callback_data); if (M.seq_no < last_seq_no) debug(81, 1) ("WARNING: sequencing out of order\n"); x = msgsnd(diskdinfo->smsgid, &M, msg_snd_rcv_sz, IPC_NOWAIT); @@ -489,8 +482,7 @@ storeDiskdSend(int mtype, SwapDir * sd, int id, storeIOState * sio, int size, in diskdinfo->away++; } else { debug(50, 1) ("storeDiskdSend: msgsnd: %s\n", xstrerror()); - if (M.callback_data) - cbdataUnlock(M.callback_data); + cbdataReferenceDone(M.callback_data); assert(++send_errors < 100); } /* diff --git a/src/fs/ufs/store_io_ufs.cc b/src/fs/ufs/store_io_ufs.cc index 1ae035da8f..242f0e5c45 100644 --- a/src/fs/ufs/store_io_ufs.cc +++ b/src/fs/ufs/store_io_ufs.cc @@ -1,6 +1,6 @@ /* - * $Id: store_io_ufs.cc,v 1.9 2001/10/24 07:45:38 hno Exp $ + * $Id: store_io_ufs.cc,v 1.10 2002/04/13 23:07:57 hno Exp $ * * DEBUG: section 79 Storage Manager UFS Interface * AUTHOR: Duane Wessels @@ -70,8 +70,7 @@ storeUfsOpen(SwapDir * SD, StoreEntry * e, STFNCB * file_callback, sio->swap_dirn = SD->index; sio->mode = O_RDONLY; sio->callback = callback; - sio->callback_data = callback_data; - cbdataLock(callback_data); + sio->callback_data = cbdataReference(callback_data); sio->e = e; ((ufsstate_t *) (sio->fsstate))->fd = fd; ((ufsstate_t *) (sio->fsstate))->flags.writing = 0; @@ -118,8 +117,7 @@ storeUfsCreate(SwapDir * SD, StoreEntry * e, STFNCB * file_callback, STIOCB * ca sio->swap_dirn = dirn; sio->mode = mode; sio->callback = callback; - sio->callback_data = callback_data; - cbdataLock(callback_data); + sio->callback_data = cbdataReference(callback_data); sio->e = (StoreEntry *) e; ((ufsstate_t *) (sio->fsstate))->fd = fd; ((ufsstate_t *) (sio->fsstate))->flags.writing = 0; @@ -154,8 +152,7 @@ storeUfsRead(SwapDir * SD, storeIOState * sio, char *buf, size_t size, off_t off assert(sio->read.callback == NULL); assert(sio->read.callback_data == NULL); sio->read.callback = callback; - sio->read.callback_data = callback_data; - cbdataLock(callback_data); + sio->read.callback_data = cbdataReference(callback_data); debug(79, 3) ("storeUfsRead: dirno %d, fileno %08X, FD %d\n", sio->swap_dirn, sio->swap_filen, ufsstate->fd); sio->offset = offset; @@ -199,8 +196,8 @@ storeUfsReadDone(int fd, const char *buf, int len, int errflag, void *my_data) { storeIOState *sio = my_data; ufsstate_t *ufsstate = (ufsstate_t *) sio->fsstate; - STRCB *callback = sio->read.callback; - void *their_data = sio->read.callback_data; + STRCB *callback; + void *cbdata; ssize_t rlen; debug(79, 3) ("storeUfsReadDone: dirno %d, fileno %08X, FD %d, len %d\n", @@ -213,13 +210,12 @@ storeUfsReadDone(int fd, const char *buf, int len, int errflag, void *my_data) rlen = (ssize_t) len; sio->offset += len; } - assert(callback); - assert(their_data); + assert(sio->read.callback); + assert(sio->read.callback_data); + callback = sio->read.callback; sio->read.callback = NULL; - sio->read.callback_data = NULL; - if (cbdataValid(their_data)) - callback(their_data, buf, (size_t) rlen); - cbdataUnlock(their_data); + if (cbdataReferenceValidDone(sio->read.callback_data, &cbdata)) + callback(cbdata, buf, (size_t) rlen); } static void @@ -244,15 +240,14 @@ static void storeUfsIOCallback(storeIOState * sio, int errflag) { ufsstate_t *ufsstate = (ufsstate_t *) sio->fsstate; + void *cbdata; debug(79, 3) ("storeUfsIOCallback: errflag=%d\n", errflag); if (ufsstate->fd > -1) { file_close(ufsstate->fd); store_open_disk_fd--; } - if (cbdataValid(sio->callback_data)) - sio->callback(sio->callback_data, errflag, sio); - cbdataUnlock(sio->callback_data); - sio->callback_data = NULL; + if (cbdataReferenceValidDone(sio->callback_data, &cbdata)) + sio->callback(cbdata, errflag, sio); sio->callback = NULL; cbdataFree(sio); } diff --git a/src/ftp.cc b/src/ftp.cc index 9eca0258d8..72ea8404a6 100644 --- a/src/ftp.cc +++ b/src/ftp.cc @@ -1,6 +1,6 @@ /* - * $Id: ftp.cc,v 1.319 2002/04/13 22:56:21 hno Exp $ + * $Id: ftp.cc,v 1.320 2002/04/13 23:07:50 hno Exp $ * * DEBUG: section 9 File Transfer Protocol (FTP) * AUTHOR: Harvest Derived @@ -2420,7 +2420,7 @@ ftpSendReply(FtpStateData * ftpState) err_type err_code = ERR_NONE; debug(9, 5) ("ftpSendReply: %s, code %d\n", storeUrl(ftpState->entry), code); - if (cbdataValid(ftpState)) + if (cbdataReferenceValid(ftpState)) debug(9, 5) ("ftpSendReply: ftpState (%p) is valid!\n", ftpState); if (code == 226) { err_code = (ftpState->mdtm > 0) ? ERR_FTP_PUT_MODIFIED : ERR_FTP_PUT_CREATED; diff --git a/src/globals.h b/src/globals.h index 0b0c55ac33..a8e3cceb1b 100644 --- a/src/globals.h +++ b/src/globals.h @@ -1,6 +1,6 @@ /* - * $Id: globals.h,v 1.109 2002/03/30 16:29:51 hno Exp $ + * $Id: globals.h,v 1.110 2002/04/13 23:07:50 hno Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -159,7 +159,7 @@ extern hash_table *proxy_auth_username_cache; /* NULL */ extern int incoming_sockets_accepted; #if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_) extern unsigned int WIN32_OS_version; /* 0 */ -extern char *WIN32_OS_string; /* NULL */ +extern char *WIN32_OS_string; /* NULL */ #endif #endif /* SQUID_GLOBALS_H */ diff --git a/src/helper.cc b/src/helper.cc index afb2b78d8c..feb0905136 100644 --- a/src/helper.cc +++ b/src/helper.cc @@ -1,6 +1,6 @@ /* - * $Id: helper.cc,v 1.34 2001/11/28 08:01:46 robertc Exp $ + * $Id: helper.cc,v 1.35 2002/04/13 23:07:50 hno Exp $ * * DEBUG: section 29 Helper process maintenance * AUTHOR: Harvest Derived? @@ -111,8 +111,7 @@ helperOpenServers(helper * hlp) srv->buf = memAllocate(MEM_8K_BUF); srv->buf_sz = 8192; srv->offset = 0; - srv->parent = hlp; - cbdataLock(hlp); /* lock because of the parent backlink */ + srv->parent = cbdataReference(hlp); dlinkAddTail(srv, &srv->link, &hlp->servers); if (rfd == wfd) { snprintf(fd_note_buf, FD_DESC_SZ, "%s #%d", shortname, k + 1); @@ -194,10 +193,9 @@ helperStatefulOpenServers(statefulhelper * hlp) srv->buf = memAllocate(MEM_8K_BUF); srv->buf_sz = 8192; srv->offset = 0; - srv->parent = hlp; + srv->parent = cbdataReference(hlp); if (hlp->datapool != NULL) srv->data = memPoolAlloc(hlp->datapool); - cbdataLock(hlp); /* lock because of the parent backlink */ dlinkAddTail(srv, &srv->link, &hlp->servers); if (rfd == wfd) { snprintf(fd_note_buf, FD_DESC_SZ, "%s #%d", shortname, k + 1); @@ -230,9 +228,8 @@ helperSubmit(helper * hlp, const char *buf, HLPCB * callback, void *data) return; } r->callback = callback; - r->data = data; + r->data = cbdataReference(data); r->buf = xstrdup(buf); - cbdataLock(r->data); if ((srv = GetFirstAvailable(hlp))) helperDispatch(srv, r); else @@ -254,7 +251,7 @@ helperStatefulSubmit(statefulhelper * hlp, const char *buf, HLPSCB * callback, v return; } r->callback = callback; - r->data = data; + r->data = cbdataReference(data); if (buf != NULL) { r->buf = xstrdup(buf); r->placeholder = 0; @@ -262,7 +259,6 @@ helperStatefulSubmit(statefulhelper * hlp, const char *buf, HLPSCB * callback, v r->buf = NULL; r->placeholder = 1; } - cbdataLock(r->data); if ((buf != NULL) && lastserver) { debug(29, 5) ("StatefulSubmit with lastserver %p\n", lastserver); /* the queue doesn't count for this assert because queued requests @@ -633,8 +629,9 @@ helperServerFree(int fd, void *data) srv->buf = NULL; } if ((r = srv->request)) { - if (cbdataValid(r->data)) - r->callback(r->data, srv->buf); + void *cbdata; + if (cbdataReferenceValidDone(r->data, &cbdata)) + r->callback(cbdata, srv->buf); helperRequestFree(r); srv->request = NULL; } @@ -649,7 +646,7 @@ helperServerFree(int fd, void *data) if (hlp->n_running < hlp->n_to_start / 2) fatalf("Too few %s processes are running", hlp->id_name); } - cbdataUnlock(srv->parent); + cbdataReferenceDone(srv->parent); cbdataFree(srv); } @@ -665,8 +662,9 @@ helperStatefulServerFree(int fd, void *data) srv->buf = NULL; } if ((r = srv->request)) { - if (cbdataValid(r->data)) - r->callback(r->data, srv, srv->buf); + void *cbdata; + if (cbdataReferenceValidDone(r->data, &cbdata)) + r->callback(cbdata, srv, srv->buf); helperStatefulRequestFree(r); srv->request = NULL; } @@ -684,7 +682,7 @@ helperStatefulServerFree(int fd, void *data) } if (srv->data != NULL) memPoolFree(hlp->datapool, srv->data); - cbdataUnlock(srv->parent); + cbdataReferenceDone(srv->parent); cbdataFree(srv); } @@ -698,7 +696,7 @@ helperHandleRead(int fd, void *data) helper_request *r; helper *hlp = srv->parent; assert(fd == srv->rfd); - assert(cbdataValid(data)); + assert(cbdataReferenceValid(data)); statCounter.syscalls.sock.reads++; len = FD_READ_METHOD(fd, srv->buf + srv->offset, srv->buf_sz - srv->offset); fd_bytes(fd, len, FD_READ); @@ -720,10 +718,14 @@ helperHandleRead(int fd, void *data) srv->offset = 0; } else if ((t = strchr(srv->buf, '\n'))) { /* end of reply found */ + HLPCB *callback; + void *cbdata; debug(29, 3) ("helperHandleRead: end of reply found\n"); *t = '\0'; - if (cbdataValid(r->data)) - r->callback(r->data, srv->buf); + callback = r->callback; + r->callback = NULL; + if (cbdataReferenceValidDone(r->data, &cbdata)) + callback(cbdata, srv->buf); srv->flags.busy = 0; srv->offset = 0; helperRequestFree(r); @@ -752,7 +754,7 @@ helperStatefulHandleRead(int fd, void *data) helper_stateful_request *r; statefulhelper *hlp = srv->parent; assert(fd == srv->rfd); - assert(cbdataValid(data)); + assert(cbdataReferenceValid(data)); statCounter.syscalls.sock.reads++; len = read(fd, srv->buf + srv->offset, srv->buf_sz - srv->offset); fd_bytes(fd, len, FD_READ); @@ -776,7 +778,7 @@ helperStatefulHandleRead(int fd, void *data) /* end of reply found */ debug(29, 3) ("helperStatefulHandleRead: end of reply found\n"); *t = '\0'; - if (cbdataValid(r->data)) { + if (cbdataReferenceValid(r->data)) { switch ((r->callback(r->data, srv, srv->buf))) { /*if non-zero reserve helper */ case S_HELPER_UNKNOWN: fatal("helperStatefulHandleRead: either a non-state aware callback was give to the stateful helper routines, or an uninitialised callback response was recieved.\n"); @@ -995,7 +997,7 @@ static void helperDispatch(helper_server * srv, helper_request * r) { helper *hlp = srv->parent; - if (!cbdataValid(r->data)) { + if (!cbdataReferenceValid(r->data)) { debug(29, 1) ("helperDispatch: invalid callback data\n"); helperRequestFree(r); return; @@ -1024,7 +1026,7 @@ static void helperStatefulDispatch(helper_stateful_server * srv, helper_stateful_request * r) { statefulhelper *hlp = srv->parent; - if (!cbdataValid(r->data)) { + if (!cbdataReferenceValid(r->data)) { debug(29, 1) ("helperStatefulDispatch: invalid callback data\n"); helperStatefulRequestFree(r); return; @@ -1103,7 +1105,7 @@ helperStatefulServerKickQueue(helper_stateful_server * srv) static void helperRequestFree(helper_request * r) { - cbdataUnlock(r->data); + cbdataReferenceDone(r->data); xfree(r->buf); memFree(r, MEM_HELPER_REQUEST); } @@ -1111,7 +1113,7 @@ helperRequestFree(helper_request * r) static void helperStatefulRequestFree(helper_stateful_request * r) { - cbdataUnlock(r->data); + cbdataReferenceDone(r->data); xfree(r->buf); memFree(r, MEM_HELPER_STATEFUL_REQUEST); } diff --git a/src/htcp.cc b/src/htcp.cc index 9f5b680008..9768175d4f 100644 --- a/src/htcp.cc +++ b/src/htcp.cc @@ -1,6 +1,6 @@ /* - * $Id: htcp.cc,v 1.38 2001/12/12 23:38:29 hno Exp $ + * $Id: htcp.cc,v 1.39 2002/04/13 23:07:50 hno Exp $ * * DEBUG: section 31 Hypertext Caching Protocol * AUTHOR: Duane Wesssels @@ -852,7 +852,7 @@ htcpInit(void) * mem.c::memCheckInit() will bail out. */ memDataInit(MEM_HTCP_SPECIFIER, "htcpSpecifier", - sizeof(htcpSpecifier), 0); + sizeof(htcpSpecifier), 0); memDataInit(MEM_HTCP_DETAIL, "htcpDetail", sizeof(htcpDetail), 0); htcpInSocket = -1; debug(31, 1) ("HTCP Disabled.\n"); diff --git a/src/ident.cc b/src/ident.cc index 086f217ea5..d349bf1384 100644 --- a/src/ident.cc +++ b/src/ident.cc @@ -1,6 +1,6 @@ /* - * $Id: ident.cc,v 1.58 2001/04/14 00:03:23 hno Exp $ + * $Id: ident.cc,v 1.59 2002/04/13 23:07:50 hno Exp $ * * DEBUG: section 30 Ident (RFC 931) * AUTHOR: Duane Wessels @@ -70,10 +70,10 @@ identCallback(IdentStateData * state, char *result) if (result && *result == '\0') result = NULL; while ((client = state->clients)) { + void *cbdata; state->clients = client->next; - if (cbdataValid(client->callback_data)) - client->callback(result, client->callback_data); - cbdataUnlock(client->callback_data); + if (cbdataReferenceValidDone(client->callback_data, &cbdata)) + client->callback(result, cbdata); xfree(client); } } @@ -109,10 +109,10 @@ identConnectDone(int fd, int status, void *data) return; } /* - * see if our clients still care + * see if any of our clients still care */ for (c = state->clients; c; c = c->next) { - if (cbdataValid(c->callback_data)) + if (cbdataReferenceValid(c->callback_data)) break; } if (c == NULL) { @@ -172,8 +172,7 @@ identClientAdd(IdentStateData * state, IDCB * callback, void *callback_data) IdentClient *c = xcalloc(1, sizeof(*c)); IdentClient **C; c->callback = callback; - c->callback_data = callback_data; - cbdataLock(callback_data); + c->callback_data = cbdataReference(callback_data); for (C = &state->clients; *C; C = &(*C)->next); *C = c; } diff --git a/src/ipcache.cc b/src/ipcache.cc index 5a1a0078d5..27c4e65905 100644 --- a/src/ipcache.cc +++ b/src/ipcache.cc @@ -1,6 +1,6 @@ /* - * $Id: ipcache.cc,v 1.236 2001/11/13 22:16:24 hno Exp $ + * $Id: ipcache.cc,v 1.237 2002/04/13 23:07:50 hno Exp $ * * DEBUG: section 14 IP Cache * AUTHOR: Harvest Derived @@ -214,19 +214,18 @@ ipcacheAddEntry(ipcache_entry * i) static void ipcacheCallback(ipcache_entry * i) { - IPH *handler = i->handler; - void *handlerData = i->handlerData; + IPH *callback = i->handler; + void *cbdata; i->lastref = squid_curtime; - ipcacheLockEntry(i); - if (NULL == handler) + if (!i->handler) return; + ipcacheLockEntry(i); + callback = i->handler; i->handler = NULL; - i->handlerData = NULL; - if (cbdataValid(handlerData)) { + if (cbdataReferenceValidDone(i->handlerData, &cbdata)) { dns_error_message = i->error_message; - handler(i->flags.negcached ? NULL : &i->addrs, handlerData); + callback(i->flags.negcached ? NULL : &i->addrs, cbdata); } - cbdataUnlock(handlerData); ipcacheUnlockEntry(i); } @@ -420,8 +419,7 @@ ipcache_nbgethostbyname(const char *name, IPH * handler, void *handlerData) else IpcacheStats.hits++; i->handler = handler; - i->handlerData = handlerData; - cbdataLock(handlerData); + i->handlerData = cbdataReference(handlerData); ipcacheCallback(i); return; } @@ -429,8 +427,7 @@ ipcache_nbgethostbyname(const char *name, IPH * handler, void *handlerData) IpcacheStats.misses++; i = ipcacheCreateEntry(name); i->handler = handler; - i->handlerData = handlerData; - cbdataLock(handlerData); + i->handlerData = cbdataReference(handlerData); i->request_time = current_time; c = cbdataAlloc(generic_cbdata); c->data = i; diff --git a/src/mem.cc b/src/mem.cc index 0d91386b2b..1e07b2afc9 100644 --- a/src/mem.cc +++ b/src/mem.cc @@ -1,6 +1,6 @@ /* - * $Id: mem.cc,v 1.64 2002/04/06 15:24:41 hno Exp $ + * $Id: mem.cc,v 1.65 2002/04/13 23:07:50 hno Exp $ * * DEBUG: section 13 High Level Memory Pool Management * AUTHOR: Harvest Derived @@ -107,7 +107,7 @@ memStringStats(StoreEntry * sentry) } static void -memBufStats(StoreEntry *sentry) +memBufStats(StoreEntry * sentry) { storeAppendPrintf(sentry, "Large buffers: %d (%d KB)\n", HugeBufCountMeter.level, @@ -217,24 +217,24 @@ memFindBufSizeType(size_t net_size, size_t * gross_size) { mem_type type; size_t size; - if (net_size <= 2*1024) { + if (net_size <= 2 * 1024) { type = MEM_2K_BUF; - size = 2*1024; - } else if (net_size <= 4*1024) { + size = 2 * 1024; + } else if (net_size <= 4 * 1024) { type = MEM_4K_BUF; - size = 4*1024; - } else if (net_size <= 8*1024) { + size = 4 * 1024; + } else if (net_size <= 8 * 1024) { type = MEM_8K_BUF; - size = 8*1024; - } else if (net_size <= 16*1024) { + size = 8 * 1024; + } else if (net_size <= 16 * 1024) { type = MEM_16K_BUF; - size = 16*1024; - } else if (net_size <= 32*1024) { + size = 16 * 1024; + } else if (net_size <= 32 * 1024) { type = MEM_32K_BUF; - size = 32*1024; - } else if (net_size <= 64*1024) { + size = 32 * 1024; + } else if (net_size <= 64 * 1024) { type = MEM_64K_BUF; - size = 64*1024; + size = 64 * 1024; } else { type = MEM_NONE; size = net_size; @@ -430,6 +430,7 @@ memPoolDescribe(const MemPool * pool) pool->label, memPoolInUseCount(pool), pool->obj_size, toKB(pool->obj_size * pool->meter.inuse.level)); } + #endif void @@ -491,19 +492,18 @@ memFree64K(void *p) FREE * memFreeBufFunc(size_t size) { - switch(size) - { - case 2*1024: + switch (size) { + case 2 * 1024: return memFree2K; - case 4*1024: + case 4 * 1024: return memFree4K; - case 8*1024: + case 8 * 1024: return memFree8K; - case 16*1024: + case 16 * 1024: return memFree16K; - case 32*1024: + case 32 * 1024: return memFree32K; - case 64*1024: + case 64 * 1024: return memFree64K; default: memMeterDec(HugeBufCountMeter); @@ -650,6 +650,6 @@ memReport(StoreEntry * e) storeAppendPrintf(e, "Idle pool limit: %.2f MB\n", toMB(mp_total.mem_idle_limit)); /* limits */ storeAppendPrintf(e, "Total Pools created: %d\n", mp_total.tot_pools_alloc); - storeAppendPrintf(e, "Pools ever used: %d (shown above)\n",mp_total.tot_pools_alloc - not_used); + storeAppendPrintf(e, "Pools ever used: %d (shown above)\n", mp_total.tot_pools_alloc - not_used); storeAppendPrintf(e, "Currently in use: %d\n", mp_total.tot_pools_inuse); } diff --git a/src/neighbors.cc b/src/neighbors.cc index 8d5772c855..0f6cd9d84f 100644 --- a/src/neighbors.cc +++ b/src/neighbors.cc @@ -1,6 +1,6 @@ /* - * $Id: neighbors.cc,v 1.300 2002/04/07 03:35:30 hno Exp $ + * $Id: neighbors.cc,v 1.301 2002/04/13 23:07:51 hno Exp $ * * DEBUG: section 15 Neighbor Routines * AUTHOR: Harvest Derived @@ -957,11 +957,7 @@ peerDestroy(void *data) } safe_free(p->host); #if USE_CACHE_DIGESTS - if (p->digest) { - PeerDigest *pd = p->digest; - p->digest = NULL; - cbdataUnlock(pd); - } + cbdataReferenceDone(p->digest); #endif } @@ -969,11 +965,7 @@ void peerNoteDigestGone(peer * p) { #if USE_CACHE_DIGESTS - if (p->digest) { - PeerDigest *pd = p->digest; - p->digest = NULL; - cbdataUnlock(pd); - } + cbdataReferenceDone(p->digest); #endif } diff --git a/src/net_db.cc b/src/net_db.cc index db9f838240..53282b77c1 100644 --- a/src/net_db.cc +++ b/src/net_db.cc @@ -1,6 +1,6 @@ /* - * $Id: net_db.cc,v 1.159 2002/02/26 15:48:15 adrian Exp $ + * $Id: net_db.cc,v 1.160 2002/04/13 23:07:51 hno Exp $ * * DEBUG: section 38 Network Measurement Database * AUTHOR: Duane Wessels @@ -47,9 +47,9 @@ #define NETDB_REQBUF_SZ 4096 typedef enum { - STATE_NONE, - STATE_HEADER, - STATE_BODY + STATE_NONE, + STATE_HEADER, + STATE_BODY } netdb_conn_state_t; typedef struct { @@ -564,8 +564,10 @@ netdbExchangeHandleReply(void *data, char *notused, ssize_t retsize) rec_sz += 1 + sizeof(addr.s_addr); rec_sz += 1 + sizeof(int); rec_sz += 1 + sizeof(int); + ex->seen = ex->used + size; + debug(38, 3) ("netdbExchangeHandleReply: %d bytes\n", (int) size); debug(38, 3) ("netdbExchangeHandleReply: %d read bytes\n", (int) retsize); - if (!cbdataValid(ex->p)) { + if (!cbdataReferenceValid(ex->p)) { debug(38, 3) ("netdbExchangeHandleReply: Peer became invalid\n"); netdbExchangeDone(ex); return; @@ -580,7 +582,7 @@ netdbExchangeHandleReply(void *data, char *notused, ssize_t retsize) /* Check if we're still doing headers */ if (ex->connstate == STATE_HEADER) { - ex->buf_ofs += retsize; + ex->buf_ofs += retsize; /* skip reply headers */ if ((hdr_sz = headersEnd(p, ex->buf_ofs))) { @@ -596,26 +598,25 @@ netdbExchangeHandleReply(void *data, char *notused, ssize_t retsize) } assert(ex->buf_ofs >= hdr_sz); - /* - * Now, point p to the part of the buffer where the data - * starts, and update the size accordingly - */ - assert(ex->used == 0); + /* + * Now, point p to the part of the buffer where the data + * starts, and update the size accordingly + */ + assert(ex->used == 0); ex->used = hdr_sz; size = ex->buf_ofs - hdr_sz; p += hdr_sz; - /* Finally, set the conn state mode to STATE_BODY */ - ex->connstate = STATE_BODY; + /* Finally, set the conn state mode to STATE_BODY */ + ex->connstate = STATE_BODY; } else { - /* Have more headers .. */ - storeClientCopy(ex->sc, ex->e, ex->buf_ofs, - ex->buf_sz - ex->buf_ofs, ex->buf + ex->buf_ofs, - netdbExchangeHandleReply, ex); - return; + /* Have more headers .. */ + storeClientCopy(ex->sc, ex->e, ex->buf_ofs, + ex->buf_sz - ex->buf_ofs, ex->buf + ex->buf_ofs, + netdbExchangeHandleReply, ex); + return; } } - assert(ex->connstate == STATE_BODY); /* If we get here, we have some body to parse .. */ @@ -657,7 +658,7 @@ netdbExchangeHandleReply(void *data, char *notused, ssize_t retsize) ex->used += rec_sz; size -= rec_sz; p += rec_sz; - nused++; + nused++; } /* @@ -690,7 +691,7 @@ netdbExchangeHandleReply(void *data, char *notused, ssize_t retsize) debug(38, 3) ("netdbExchangeHandleReply: used %d entries, (x %d bytes) == %d bytes total\n", nused, rec_sz, nused * rec_sz); - debug(38, 3) ("netdbExchangeHandleReply: used %ld\n",(long int) ex->used); + debug(38, 3) ("netdbExchangeHandleReply: used %ld\n", (long int) ex->used); if (EBIT_TEST(ex->e->flags, ENTRY_ABORTED)) { debug(38, 3) ("netdbExchangeHandleReply: ENTRY_ABORTED\n"); netdbExchangeDone(ex); @@ -716,7 +717,7 @@ netdbExchangeDone(void *data) requestUnlink(ex->r); storeUnregister(ex->sc, ex->e, ex); storeUnlockObject(ex->e); - cbdataUnlock(ex->p); + cbdataReferenceDone(ex->p); cbdataFree(ex); } @@ -1062,8 +1063,7 @@ netdbExchangeStart(void *data) netdbExchangeState *ex; CBDATA_INIT_TYPE(netdbExchangeState); ex = cbdataAlloc(netdbExchangeState); - cbdataLock(p); - ex->p = p; + ex->p = cbdataReference(p); uri = internalRemoteUri(p->host, p->http_port, "/squid-internal-dynamic/", "netdb"); debug(38, 3) ("netdbExchangeStart: Requesting '%s'\n", uri); assert(NULL != uri); @@ -1081,7 +1081,7 @@ netdbExchangeStart(void *data) assert(NULL != ex->e); ex->sc = storeClientListAdd(ex->e, ex); storeClientCopy(ex->sc, ex->e, 0, ex->buf_sz, ex->buf, - netdbExchangeHandleReply, ex); + netdbExchangeHandleReply, ex); ex->r->flags.loopdetect = 1; /* cheat! -- force direct */ if (p->login) xstrncpy(ex->r->login, p->login, MAX_LOGIN_SZ); diff --git a/src/pconn.cc b/src/pconn.cc index 11a52e6712..9989608437 100644 --- a/src/pconn.cc +++ b/src/pconn.cc @@ -1,6 +1,6 @@ /* - * $Id: pconn.cc,v 1.31 2001/04/14 00:03:23 hno Exp $ + * $Id: pconn.cc,v 1.32 2002/04/13 23:07:51 hno Exp $ * * DEBUG: section 48 Persistent Connections * AUTHOR: Duane Wessels @@ -41,6 +41,7 @@ struct _pconn { int nfds_alloc; int nfds; }; +typedef struct _pconn pconn; #define PCONN_FDS_SZ 8 /* pconn set size, increase for better memcache hit rate */ #define PCONN_HIST_SZ (1<<16) @@ -55,8 +56,10 @@ static struct _pconn *pconnNew(const char *key); static void pconnDelete(struct _pconn *p); static void pconnRemoveFD(struct _pconn *p, int fd); static OBJH pconnHistDump; -static MemPool *pconn_data_pool = NULL; static MemPool *pconn_fds_pool = NULL; +CBDATA_TYPE(pconn); + + static const char * pconnKey(const char *host, u_short port) @@ -69,7 +72,9 @@ pconnKey(const char *host, u_short port) static struct _pconn * pconnNew(const char *key) { - struct _pconn *p = memPoolAlloc(pconn_data_pool); + pconn *p; + CBDATA_INIT_TYPE(pconn); + p = cbdataAlloc(pconn); p->hash.key = xstrdup(key); p->nfds_alloc = PCONN_FDS_SZ; p->fds = memPoolAlloc(pconn_fds_pool); @@ -88,7 +93,7 @@ pconnDelete(struct _pconn *p) else xfree(p->fds); xfree(p->hash.key); - memPoolFree(pconn_data_pool, p); + cbdataFree(p); } static void @@ -174,7 +179,6 @@ pconnInit(void) client_pconn_hist[i] = 0; server_pconn_hist[i] = 0; } - pconn_data_pool = memPoolCreate("pconn_data", sizeof(struct _pconn)); pconn_fds_pool = memPoolCreate("pconn_fds", PCONN_FDS_SZ * sizeof(int)); cachemgrRegister("pconn", diff --git a/src/peer_digest.cc b/src/peer_digest.cc index fa0385cf80..45af818c07 100644 --- a/src/peer_digest.cc +++ b/src/peer_digest.cc @@ -1,6 +1,6 @@ /* - * $Id: peer_digest.cc,v 1.84 2002/02/26 15:48:15 adrian Exp $ + * $Id: peer_digest.cc,v 1.85 2002/04/13 23:07:51 hno Exp $ * * DEBUG: section 72 Peer Digest Routines * AUTHOR: Alex Rousskov @@ -110,9 +110,9 @@ peerDigestCreate(peer * p) CBDATA_INIT_TYPE(PeerDigest); pd = cbdataAlloc(PeerDigest); peerDigestInit(pd, p); - cbdataLock(pd->peer); /* we will use the peer */ - return pd; + /* XXX This does not look right, and the same thing again in the caller */ + return cbdataReference(pd); } /* call Clean and free/unlock everything */ @@ -122,12 +122,12 @@ peerDigestDestroy(PeerDigest * pd) peer *p; assert(pd); + /* inform peer (if any) that we are gone */ p = pd->peer; pd->peer = NULL; - /* inform peer (if any) that we are gone */ - if (cbdataValid(p)) + if (cbdataReferenceValid(p)) peerNoteDigestGone(p); - cbdataUnlock(p); /* must unlock, valid or not */ + cbdataReferenceDone(p); peerDigestClean(pd); cbdataFree(pd); @@ -224,14 +224,14 @@ peerDigestCheck(void *data) time_t req_time; /* - * you can't assert(cbdataValid(pd)) -- if its not valid this + * you can't assert(cbdataReferenceValid(pd)) -- if its not valid this * function never gets called */ assert(!pd->flags.requested); pd->times.next_check = 0; /* unknown */ - if (!cbdataValid(pd->peer)) { + if (!cbdataReferenceValid(pd->peer)) { peerDigestNotePeerGone(pd); return; } @@ -301,7 +301,7 @@ peerDigestRequest(PeerDigest * pd) CBDATA_INIT_TYPE(DigestFetchState); fetch = cbdataAlloc(DigestFetchState); fetch->request = requestLink(req); - fetch->pd = pd; + fetch->pd = cbdataReference(pd); fetch->offset = 0; fetch->state = DIGEST_READ_REPLY; @@ -330,8 +330,6 @@ peerDigestRequest(PeerDigest * pd) /* push towards peer cache */ debug(72, 3) ("peerDigestRequest: forwarding to fwdStart...\n"); fwdStart(-1, e, req); - cbdataLock(fetch); - cbdataLock(fetch->pd); storeClientCopy(fetch->sc, e, 0, SM_PAGE_SIZE, fetch->buf, peerDigestHandleReply, fetch); } @@ -367,44 +365,46 @@ peerDigestHandleReply(void *data, char *buf, ssize_t copysize) /* Call the right function based on the state */ /* (Those functions will update the state if needed) */ - cbdataLock(fetch); + + /* Lock our data to protect us from ourselves */ + cbdataInternalLock(fetch); /* Repeat this loop until we're out of data OR the state changes */ /* (So keep going if the state has changed and we still have data */ do { - prevstate = fetch->state; - switch(fetch->state) { - case DIGEST_READ_REPLY: - retsize = peerDigestFetchReply(data, fetch->buf, fetch->bufofs); - break; - case DIGEST_READ_HEADERS: - retsize = peerDigestSwapInHeaders(data, fetch->buf, fetch->bufofs); - break; - case DIGEST_READ_CBLOCK: - retsize = peerDigestSwapInCBlock(data, fetch->buf, fetch->bufofs); - break; - case DIGEST_READ_MASK: - retsize = peerDigestSwapInMask(data, fetch->buf, fetch->bufofs); - break; - case DIGEST_READ_NONE: - break; - case DIGEST_READ_DONE: - goto finish; - break; - default: - fatal("Bad digest transfer mode!\n"); - } - - if (retsize < 0) - goto finish; - /* - * The returned size indicates how much of the buffer was read - - * so move the remainder of the buffer to the beginning - * and update the bufofs / bufsize - */ - newsize = fetch->bufofs - retsize; - xmemmove(fetch->buf, fetch->buf + retsize, fetch->bufofs - newsize); - fetch->bufofs = newsize; + prevstate = fetch->state; + switch (fetch->state) { + case DIGEST_READ_REPLY: + retsize = peerDigestFetchReply(data, fetch->buf, fetch->bufofs); + break; + case DIGEST_READ_HEADERS: + retsize = peerDigestSwapInHeaders(data, fetch->buf, fetch->bufofs); + break; + case DIGEST_READ_CBLOCK: + retsize = peerDigestSwapInCBlock(data, fetch->buf, fetch->bufofs); + break; + case DIGEST_READ_MASK: + retsize = peerDigestSwapInMask(data, fetch->buf, fetch->bufofs); + break; + case DIGEST_READ_NONE: + break; + case DIGEST_READ_DONE: + goto finish; + break; + default: + fatal("Bad digest transfer mode!\n"); + } + + if (retsize < 0) + goto finish; + /* + * The returned size indicates how much of the buffer was read - + * so move the remainder of the buffer to the beginning + * and update the bufofs / bufsize + */ + newsize = fetch->bufofs - retsize; + xmemmove(fetch->buf, fetch->buf + retsize, fetch->bufofs - newsize); + fetch->bufofs = newsize; } while (prevstate != fetch->state && fetch->bufofs > 0); @@ -412,13 +412,13 @@ peerDigestHandleReply(void *data, char *buf, ssize_t copysize) fetch->offset += copysize; /* Schedule another copy */ - if (cbdataValid(fetch)) { - storeClientCopy(fetch->sc, fetch->entry, fetch->offset, SM_PAGE_SIZE - fetch->bufofs, - fetch->buf + fetch->bufofs, peerDigestHandleReply, fetch); + if (cbdataReferenceValid(fetch)) { + storeClientCopy(fetch->sc, fetch->entry, fetch->offset, SM_PAGE_SIZE - fetch->bufofs, + fetch->buf + fetch->bufofs, peerDigestHandleReply, fetch); } -finish: + finish: /* Unlock our data - we've finished with it for now */ - cbdataUnlock(fetch); + cbdataInternalUnlock(fetch); } @@ -484,7 +484,7 @@ peerDigestFetchReply(void *data, char *buf, ssize_t size) } else { /* some kind of a bug */ peerDigestFetchAbort(fetch, buf, httpStatusLineReason(&reply->sline)); - return -1; /* XXX -1 will abort stuff in ReadReply! */ + return -1; /* XXX -1 will abort stuff in ReadReply! */ } /* must have a ready-to-use store entry if we got here */ /* can we stay with the old in-memory digest? */ @@ -493,7 +493,7 @@ peerDigestFetchReply(void *data, char *buf, ssize_t size) fetch->state = DIGEST_READ_DONE; } else { fetch->state = DIGEST_READ_HEADERS; - } + } } else { /* need more data, do we have space? */ if (size >= SM_PAGE_SIZE) @@ -528,15 +528,15 @@ peerDigestSwapInHeaders(void *data, char *buf, ssize_t size) return -1; } fetch->state = DIGEST_READ_CBLOCK; - return hdr_size; /* Say how much data we read */ + return hdr_size; /* Say how much data we read */ } else { /* need more data, do we have space? */ if (size >= SM_PAGE_SIZE) { peerDigestFetchAbort(fetch, buf, "stored header too big"); return -1; } else { - return 0; /* We need to read more to parse .. */ - } + return 0; /* We need to read more to parse .. */ + } } fatal("peerDigestSwapInHeaders() - shouldn't get here!\n"); } @@ -560,20 +560,20 @@ peerDigestSwapInCBlock(void *data, char *buf, ssize_t size) /* switch to CD buffer and fetch digest guts */ buf = NULL; assert(pd->cd->mask); - fetch->state = DIGEST_READ_MASK; - return StoreDigestCBlockSize; + fetch->state = DIGEST_READ_MASK; + return StoreDigestCBlockSize; } else { peerDigestFetchAbort(fetch, buf, "invalid digest cblock"); - return -1; + return -1; } } else { /* need more data, do we have space? */ if (size >= SM_PAGE_SIZE) { peerDigestFetchAbort(fetch, buf, "digest cblock too big"); - return -1; - } else { - return 0; /* We need more data */ - } + return -1; + } else { + return 0; /* We need more data */ + } } fatal("peerDigestSwapInCBlock(): shouldn't get here!\n"); } @@ -603,10 +603,10 @@ peerDigestSwapInMask(void *data, char *buf, ssize_t size) fetch->mask_offset, pd->cd->mask_size); assert(fetch->mask_offset == pd->cd->mask_size); assert(peerDigestFetchedEnough(fetch, NULL, 0, "peerDigestSwapInMask")); - return -1; /* XXX! */ + return -1; /* XXX! */ } else { - /* We always read everything, so return so */ - return size; + /* We always read everything, so return so */ + return size; } fatal("peerDigestSwapInMask(): shouldn't get here!\n"); } @@ -618,9 +618,9 @@ peerDigestFetchedEnough(DigestFetchState * fetch, char *buf, ssize_t size, const const char *host = ""; /* peer host */ const char *reason = NULL; /* reason for completion */ const char *no_bug = NULL; /* successful completion if set */ - const int fcb_valid = cbdataValid(fetch); - const int pdcb_valid = fcb_valid && cbdataValid(fetch->pd); - const int pcb_valid = pdcb_valid && cbdataValid(fetch->pd->peer); + const int fcb_valid = cbdataReferenceValid(fetch); + const int pdcb_valid = fcb_valid && cbdataReferenceValid(fetch->pd); + const int pcb_valid = pdcb_valid && cbdataReferenceValid(fetch->pd->peer); /* test possible exiting conditions (the same for most steps!) * cases marked with '?!' should not happen */ @@ -631,7 +631,7 @@ peerDigestFetchedEnough(DigestFetchState * fetch, char *buf, ssize_t size, const else if (!(pd = fetch->pd)) reason = "peer digest disappeared?!"; #if DONT - else if (!cbdataValid(pd)) + else if (!cbdataReferenceValid(pd)) reason = "invalidated peer digest?!"; #endif else @@ -642,7 +642,7 @@ peerDigestFetchedEnough(DigestFetchState * fetch, char *buf, ssize_t size, const /* continue checking (with pd and host known and valid) */ if (!reason) { - if (!cbdataValid(pd->peer)) + if (!cbdataReferenceValid(pd->peer)) reason = "peer disappeared"; else if (size < 0) reason = "swap failure"; @@ -770,8 +770,7 @@ peerDigestPDFinish(DigestFetchState * fetch, int pcb_valid, int err) else debug(72, 2) ("received valid digest from %s\n", host); } - fetch->pd = NULL; - cbdataUnlock(pd); + cbdataReferenceDone(fetch->pd); } /* free fetch state structures @@ -801,7 +800,6 @@ peerDigestFetchFinish(DigestFetchState * fetch, int err) fetch->entry = NULL; fetch->request = NULL; assert(fetch->pd == NULL); - cbdataUnlock(fetch); cbdataFree(fetch); } diff --git a/src/peer_select.cc b/src/peer_select.cc index 331697b96d..eea01106e3 100644 --- a/src/peer_select.cc +++ b/src/peer_select.cc @@ -1,6 +1,6 @@ /* - * $Id: peer_select.cc,v 1.120 2002/04/04 21:03:46 hno Exp $ + * $Id: peer_select.cc,v 1.121 2002/04/13 23:07:51 hno Exp $ * * DEBUG: section 44 Peer Selection Algorithm * AUTHOR: Duane Wessels @@ -143,14 +143,13 @@ peerSelect(request_t * request, psstate->request = requestLink(request); psstate->entry = entry; psstate->callback = callback; - psstate->callback_data = callback_data; + psstate->callback_data = cbdataReference(callback_data); psstate->direct = DIRECT_UNKNOWN; #if USE_CACHE_DIGESTS request->hier.peer_select_start = current_time; #endif if (psstate->entry) storeLockObject(psstate->entry); - cbdataLock(callback_data); peerSelectFoo(psstate); } @@ -179,7 +178,8 @@ peerSelectCallback(ps_state * psstate) { StoreEntry *entry = psstate->entry; FwdServer *fs = psstate->servers; - void *data = psstate->callback_data; + PSC *callback; + void *cbdata; if (entry) { debug(44, 3) ("peerSelectCallback: %s\n", storeUrl(entry)); if (entry->ping_status == PING_WAITING) @@ -194,11 +194,12 @@ peerSelectCallback(ps_state * psstate) } psstate->ping.stop = current_time; psstate->request->hier.ping = psstate->ping; - if (cbdataValid(data)) { + callback = psstate->callback; + psstate->callback = NULL; + if (cbdataReferenceValidDone(psstate->callback_data, &cbdata)) { psstate->servers = NULL; - psstate->callback(fs, data); + callback(fs, cbdata); } - cbdataUnlock(data); peerSelectStateFree(psstate); } @@ -491,10 +492,10 @@ peerPingTimeout(void *data) StoreEntry *entry = psstate->entry; if (entry) debug(44, 3) ("peerPingTimeout: '%s'\n", storeUrl(entry)); - if (!cbdataValid(psstate->callback_data)) { + if (!cbdataReferenceValid(psstate->callback_data)) { /* request aborted */ entry->ping_status = PING_DONE; - cbdataUnlock(psstate->callback_data); + cbdataReferenceDone(psstate->callback_data); peerSelectStateFree(psstate); return; } @@ -650,9 +651,8 @@ peerAddFwdServer(FwdServer ** FS, peer * p, hier_code code) debug(44, 5) ("peerAddFwdServer: adding %s %s\n", p ? p->host : "DIRECT", hier_strings[code]); - fs->peer = p; + fs->peer = cbdataReference(p); fs->code = code; - cbdataLock(fs->peer); while (*FS) FS = &(*FS)->next; *FS = fs; diff --git a/src/protos.h b/src/protos.h index ee9c2d8d29..6c7e26151b 100644 --- a/src/protos.h +++ b/src/protos.h @@ -1,6 +1,6 @@ /* - * $Id: protos.h,v 1.432 2002/04/06 08:49:27 adrian Exp $ + * $Id: protos.h,v 1.433 2002/04/13 23:07:51 hno Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -109,20 +109,20 @@ extern void parse_sockaddr_in_list_token(sockaddr_in_list **, char *); */ extern void cbdataInit(void); #if CBDATA_DEBUG -extern void *cbdataInternalAllocDbg(cbdata_type type, int, const char *); -extern void cbdataLockDbg(const void *p, const char *, int); -extern void cbdataUnlockDbg(const void *p, const char *, int); +extern void *cbdataInternalAllocDbg(cbdata_type type, const char *, int); +extern void *cbdataInternalFreeDbg(void *p, const char *, int); +extern void cbdataInternalLockDbg(const void *p, const char *, int); +extern void cbdataInternalUnlockDbg(const void *p, const char *, int); +extern int cbdataInternalReferenceDoneValidDbg(void **p, void **tp, const char *, int); #else extern void *cbdataInternalAlloc(cbdata_type type); -extern void cbdataLock(const void *p); -extern void cbdataUnlock(const void *p); -#endif -/* Note: Allocations is done using the cbdataAlloc macro */ extern void *cbdataInternalFree(void *p); -extern int cbdataValid(const void *p); -extern void cbdataInitType(cbdata_type type, const char *label, int size, FREE * free_func); -extern cbdata_type cbdataAddType(cbdata_type type, const char *label, int size, FREE * free_func); -extern int cbdataLocked(const void *p); +extern void cbdataInternalLock(const void *p); +extern void cbdataInternalUnlock(const void *p); +extern int cbdataInternalReferenceDoneValid(void **p, void **tp); +#endif +extern int cbdataReferenceValid(const void *p); +extern cbdata_type cbdataInternalAddType(cbdata_type type, const char *label, int size, FREE * free_func); extern void clientdbInit(void); extern void clientdbUpdate(struct in_addr, log_type, protocol_t, size_t); @@ -851,8 +851,8 @@ extern MemPool *memPoolCreate(const char *label, size_t obj_size); extern void *memPoolAlloc(MemPool * pool); extern void memPoolFree(MemPool * pool, void *obj); extern void memPoolDestroy(MemPool ** pool); -extern MemPoolIterator * memPoolGetFirst(void); -extern MemPool * memPoolGetNext(MemPoolIterator ** iter); +extern MemPoolIterator *memPoolGetFirst(void); +extern MemPool *memPoolGetNext(MemPoolIterator ** iter); extern void memPoolSetChunkSize(MemPool * pool, size_t chunksize); extern void memPoolSetIdleLimit(size_t new_idle_limit); extern int memPoolGetStats(MemPoolStats * stats, MemPool * pool); @@ -1042,9 +1042,6 @@ extern int storeSwapOutAble(const StoreEntry * e); /* * store_client.c */ -#if STORE_CLIENT_LIST_DEBUG -extern store_client *storeClientListSearch(const MemObject * mem, void *data); -#endif extern store_client *storeClientListAdd(StoreEntry * e, void *data); extern void storeClientCopyOld(store_client *, StoreEntry *, off_t, off_t, size_t, char *, STCB *, void *); extern void storeClientCopy(store_client *, StoreEntry *, off_t, size_t, char *, STCB *, void *); diff --git a/src/redirect.cc b/src/redirect.cc index c1364a5fdb..6c2545d237 100644 --- a/src/redirect.cc +++ b/src/redirect.cc @@ -1,6 +1,6 @@ /* - * $Id: redirect.cc,v 1.89 2002/04/04 23:59:25 hno Exp $ + * $Id: redirect.cc,v 1.90 2002/04/13 23:07:51 hno Exp $ * * DEBUG: section 29 Redirector * AUTHOR: Duane Wessels @@ -55,8 +55,8 @@ static void redirectHandleReply(void *data, char *reply) { redirectStateData *r = data; - int valid; char *t; + void *cbdata; debug(29, 5) ("redirectHandleRead: {%s}\n", reply ? reply : ""); if (reply) { if ((t = strchr(reply, ' '))) @@ -64,10 +64,8 @@ redirectHandleReply(void *data, char *reply) if (*reply == '\0') reply = NULL; } - valid = cbdataValid(r->data); - cbdataUnlock(r->data); - if (valid) - r->handler(r->data, reply); + if (cbdataReferenceValidDone(r->data, &cbdata)) + r->handler(cbdata, reply); redirectStateFree(r); } @@ -135,8 +133,7 @@ redirectStart(clientHttpRequest * http, RH * handler, void *data) } r->method_s = RequestMethodStr[http->request->method]; r->handler = handler; - r->data = data; - cbdataLock(r->data); + r->data = cbdataReference(data); if ((fqdn = fqdncache_gethostbyaddr(r->client_addr, 0)) == NULL) fqdn = dash_str; snprintf(buf, 8192, "%s %s/%s %s %s\n", diff --git a/src/squid.h b/src/squid.h index de0063c52e..e99edaeb9e 100644 --- a/src/squid.h +++ b/src/squid.h @@ -1,6 +1,6 @@ /* - * $Id: squid.h,v 1.218 2002/04/06 08:49:27 adrian Exp $ + * $Id: squid.h,v 1.219 2002/04/13 23:07:51 hno Exp $ * * AUTHOR: Duane Wessels * @@ -53,16 +53,16 @@ * directly, so this is a dirty hack! */ #if defined(_SQUID_LINUX_) -# undef CHANGE_FD_SETSIZE -# define CHANGE_FD_SETSIZE 0 -# include -# if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) -# if SQUID_MAXFD > DEFAULT_FD_SETSIZE -# include -# undef __FD_SETSIZE -# define __FD_SETSIZE SQUID_MAXFD -# endif -# endif +#undef CHANGE_FD_SETSIZE +#define CHANGE_FD_SETSIZE 0 +#include +#if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) +#if SQUID_MAXFD > DEFAULT_FD_SETSIZE +#include +#undef __FD_SETSIZE +#define __FD_SETSIZE SQUID_MAXFD +#endif +#endif #endif /* @@ -355,12 +355,6 @@ struct rusage { #define LOCAL_ARRAY(type,name,size) static type name[size] #endif -#if CBDATA_DEBUG -#define cbdataAlloc(a,b) cbdataAllocDbg(a,b,__FILE__,__LINE__) -#define cbdataLock(a) cbdataLockDbg(a,__FILE__,__LINE__) -#define cbdataUnlock(a) cbdataUnlockDbg(a,__FILE__,__LINE__) -#endif - #if USE_LEAKFINDER #define leakAdd(p) leakAddFL(p,__FILE__,__LINE__) #define leakTouch(p) leakTouchFL(p,__FILE__,__LINE__) diff --git a/src/ssl.cc b/src/ssl.cc index 926029e551..814ea993b1 100644 --- a/src/ssl.cc +++ b/src/ssl.cc @@ -1,6 +1,6 @@ /* - * $Id: ssl.cc,v 1.118 2001/10/29 16:06:31 hno Exp $ + * $Id: ssl.cc,v 1.119 2002/04/13 23:07:51 hno Exp $ * * DEBUG: section 26 Secure Sockets Layer Proxy * AUTHOR: Duane Wessels @@ -211,7 +211,7 @@ sslReadServer(int fd, void *data) kb_incr(&statCounter.server.other.kbytes_in, len); sslState->server.len += len; } - cbdataLock(sslState); + cbdataInternalLock(sslState); /* ??? should be locked by the caller... */ if (len < 0) { debug(50, ignoreErrno(errno) ? 3 : 1) ("sslReadServer: FD %d: read failure: %s\n", fd, xstrerror()); @@ -220,9 +220,9 @@ sslReadServer(int fd, void *data) } else if (len == 0) { comm_close(sslState->server.fd); } - if (cbdataValid(sslState)) + if (cbdataReferenceValid(sslState)) sslSetSelect(sslState); - cbdataUnlock(sslState); + cbdataInternalUnlock(sslState); /* ??? */ } /* Read from client side and queue it for writing to the server */ @@ -245,7 +245,7 @@ sslReadClient(int fd, void *data) kb_incr(&statCounter.client_http.kbytes_in, len); sslState->client.len += len; } - cbdataLock(sslState); + cbdataInternalLock(sslState); /* ??? should be locked by the caller... */ if (len < 0) { int level = 1; #ifdef ECONNRESET @@ -261,9 +261,9 @@ sslReadClient(int fd, void *data) } else if (len == 0) { comm_close(fd); } - if (cbdataValid(sslState)) + if (cbdataReferenceValid(sslState)) sslSetSelect(sslState); - cbdataUnlock(sslState); + cbdataInternalUnlock(sslState); /* ??? */ } /* Writes data from the client buffer to the server side */ @@ -293,16 +293,16 @@ sslWriteServer(int fd, void *data) sslState->client.len); } } - cbdataLock(sslState); + cbdataInternalLock(sslState); /* ??? should be locked by the caller... */ if (len < 0) { debug(50, ignoreErrno(errno) ? 3 : 1) ("sslWriteServer: FD %d: write failure: %s.\n", fd, xstrerror()); if (!ignoreErrno(errno)) comm_close(fd); } - if (cbdataValid(sslState)) + if (cbdataReferenceValid(sslState)) sslSetSelect(sslState); - cbdataUnlock(sslState); + cbdataInternalUnlock(sslState); /* ??? */ } /* Writes data from the server buffer to the client side */ @@ -334,16 +334,16 @@ sslWriteClient(int fd, void *data) sslState->server.len); } } - cbdataLock(sslState); + cbdataInternalLock(sslState); /* ??? should be locked by the caller... */ if (len < 0) { debug(50, ignoreErrno(errno) ? 3 : 1) ("sslWriteClient: FD %d: write failure: %s.\n", fd, xstrerror()); if (!ignoreErrno(errno)) comm_close(fd); } - if (cbdataValid(sslState)) + if (cbdataReferenceValid(sslState)) sslSetSelect(sslState); - cbdataUnlock(sslState); + cbdataInternalUnlock(sslState); /* ??? */ } static void diff --git a/src/store_client.cc b/src/store_client.cc index ce643ff617..5e8a3348e3 100644 --- a/src/store_client.cc +++ b/src/store_client.cc @@ -1,6 +1,6 @@ /* - * $Id: store_client.cc,v 1.107 2002/04/01 22:20:43 hno Exp $ + * $Id: store_client.cc,v 1.108 2002/04/13 23:07:51 hno Exp $ * * DEBUG: section 20 Storage Manager Client-Side Interface * AUTHOR: Duane Wessels @@ -67,14 +67,14 @@ storeClientWaiting(const StoreEntry * e) } #if STORE_CLIENT_LIST_DEBUG -store_client * +static store_client * storeClientListSearch(const MemObject * mem, void *data) { dlink_node *node; store_client *sc = NULL; for (node = mem->clients.head; node; node = node->next) { sc = node->data; - if (sc->callback_data == data) + if (sc->owner == data) return sc; } return NULL; @@ -134,8 +134,9 @@ storeClientListAdd(StoreEntry * e, void *data) e->refcount++; mem->nclients++; sc = cbdataAlloc(store_client); - cbdataLock(data); /* locked while we point to it */ - sc->callback_data = data; +#if STORE_CLIENT_LIST_DEBUG + sc->owner = cbdataReference(data); +#endif sc->copy_offset = 0; sc->cmp_offset = 0; sc->flags.disk_io_pending = 0; @@ -156,13 +157,14 @@ static void storeClientCallback(store_client * sc, ssize_t sz) { STCB *callback = sc->callback; + void *cbdata; char *buf = sc->copy_buf; assert(sc->callback); sc->cmp_offset = sc->copy_offset + sz; sc->callback = NULL; sc->copy_buf = NULL; - if (cbdataValid(sc->callback_data)) - callback(sc->callback_data, buf, sz); + if (cbdataReferenceValidDone(sc->callback_data, &cbdata)) + callback(cbdata, buf, sz); } static void @@ -177,8 +179,8 @@ storeClientCopyEvent(void *data) } void -storeClientCopyOld(store_client *sc, StoreEntry *e, off_t seen_offset, - off_t copy_offset, size_t size, char *buf, STCB *callback, void *data) +storeClientCopyOld(store_client * sc, StoreEntry * e, off_t seen_offset, + off_t copy_offset, size_t size, char *buf, STCB * callback, void *data) { /* OLD API -- adrian */ fatal("storeClientCopyOld() has been called!\n"); @@ -211,6 +213,7 @@ storeClientCopy(store_client * sc, assert(sc->cmp_offset == copy_offset); sc->copy_offset = copy_offset; sc->callback = callback; + sc->callback_data = cbdataReference(data); sc->copy_buf = buf; sc->copy_size = size; sc->copy_offset = copy_offset; @@ -243,8 +246,9 @@ storeClientNoMoreToSend(StoreEntry * e, store_client * sc) static void storeClientCopy2(StoreEntry * e, store_client * sc) { - if (sc->flags.copy_event_pending) + if (sc->flags.copy_event_pending) { return; + } if (EBIT_TEST(e->flags, ENTRY_FWD_HDR_WAIT)) { debug(20, 5) ("storeClientCopy2: returning because ENTRY_FWD_HDR_WAIT set\n"); return; @@ -255,7 +259,6 @@ storeClientCopy2(StoreEntry * e, store_client * sc) eventAdd("storeClientCopyEvent", storeClientCopyEvent, sc, 0.0, 0); return; } - cbdataLock(sc); /* ick, prevent sc from getting freed */ sc->flags.store_copying = 1; debug(20, 3) ("storeClientCopy2: %s\n", storeKeyText(e->hash.key)); assert(sc->callback != NULL); @@ -266,9 +269,14 @@ storeClientCopy2(StoreEntry * e, store_client * sc) * if the server-side aborts, we want to give the client(s) * everything we got before the abort condition occurred. */ + /* Warning: storeClientCopy3 may indirectly free sc in callbacks, + * hence the cbdata reference to keep it active for the duration of + * this function + */ + cbdataInternalLock(sc); storeClientCopy3(e, sc); sc->flags.store_copying = 0; - cbdataUnlock(sc); /* ick, allow sc to be freed */ + cbdataInternalUnlock(sc); } static void @@ -277,20 +285,18 @@ storeClientCopy3(StoreEntry * e, store_client * sc) MemObject *mem = e->mem_obj; size_t sz; - debug(33, 5) ("co: %ld, hi: %ld\n", (long int)sc->copy_offset, (long int)mem->inmem_hi); + debug(33, 5) ("co: %ld, hi: %ld\n", (long int) sc->copy_offset, (long int) mem->inmem_hi); if (storeClientNoMoreToSend(e, sc)) { /* There is no more to send! */ storeClientCallback(sc, 0); return; } - /* Check that we actually have data */ if (e->store_status == STORE_PENDING && sc->copy_offset >= mem->inmem_hi) { - debug(20, 3) ("storeClientCopy3: Waiting for more\n"); - return; + debug(20, 3) ("storeClientCopy3: Waiting for more\n"); + return; } - /* * Slight weirdness here. We open a swapin file for any * STORE_DISK_CLIENT, even if we can copy the requested chunk @@ -302,7 +308,7 @@ storeClientCopy3(StoreEntry * e, store_client * sc) * is clientCacheHit) so that we can fall back to a cache miss * if needed. */ - + if (STORE_DISK_CLIENT == sc->type && NULL == sc->swapin_sio) { debug(20, 3) ("storeClientCopy3: Need to open swap in file\n"); /* gotta open the swapin file */ @@ -328,12 +334,12 @@ storeClientCopy3(StoreEntry * e, store_client * sc) } if (sc->copy_offset >= mem->inmem_lo && sc->copy_offset < mem->inmem_hi) { /* What the client wants is in memory */ - /* Old style */ - debug(20, 3) ("storeClientCopy3: Copying normal from memory\n"); - sz = stmemCopy(&mem->data_hdr, sc->copy_offset, sc->copy_buf, - sc->copy_size); - storeClientCallback(sc, sz); - return; + /* Old style */ + debug(20, 3) ("storeClientCopy3: Copying normal from memory\n"); + sz = stmemCopy(&mem->data_hdr, sc->copy_offset, sc->copy_buf, + sc->copy_size); + storeClientCallback(sc, sz); + return; } /* What the client wants is not in memory. Schedule a disk read */ assert(STORE_DISK_CLIENT == sc->type); @@ -541,8 +547,7 @@ storeUnregister(store_client * sc, StoreEntry * e, void *data) storeSwapOut(e); if (sc->swapin_sio) { storeClose(sc->swapin_sio); - cbdataUnlock(sc->swapin_sio); - sc->swapin_sio = NULL; + cbdataReferenceDone(sc->swapin_sio); statCounter.swap.ins++; } if (NULL != sc->callback) { @@ -554,8 +559,9 @@ storeUnregister(store_client * sc, StoreEntry * e, void *data) #if DELAY_POOLS delayUnregisterDelayIdPtr(&sc->delay_id); #endif - cbdataUnlock(sc->callback_data); /* we're done with it now */ - /*assert(!sc->flags.disk_io_pending); */ +#if STORE_CLIENT_LIST_DEBUG + cbdataReferenceDone(sc->owner); +#endif cbdataFree(sc); assert(e->lock_count > 0); if (mem->nclients == 0) @@ -575,8 +581,6 @@ storeLowestMemReaderOffset(const StoreEntry * entry) for (node = mem->clients.head; node; node = nx) { sc = node->data; nx = node->next; - if (sc->callback_data == NULL) /* open slot */ - continue; if (sc->type != STORE_MEM_CLIENT) continue; if (sc->type == STORE_DISK_CLIENT) diff --git a/src/store_swapin.cc b/src/store_swapin.cc index e6da0c08e9..0e02c294d4 100644 --- a/src/store_swapin.cc +++ b/src/store_swapin.cc @@ -1,6 +1,6 @@ /* - * $Id: store_swapin.cc,v 1.28 2001/01/12 00:37:22 wessels Exp $ + * $Id: store_swapin.cc,v 1.29 2002/04/13 23:07:51 hno Exp $ * * DEBUG: section 20 Storage Manager Swapin Functions * AUTHOR: Duane Wessels @@ -42,6 +42,7 @@ void storeSwapInStart(store_client * sc) { StoreEntry *e = sc->entry; + storeIOState *sio; assert(e->mem_status == NOT_IN_MEMORY); if (!EBIT_TEST(e->flags, ENTRY_VALIDATED)) { /* We're still reloading and haven't validated this entry yet */ @@ -61,9 +62,8 @@ storeSwapInStart(store_client * sc) assert(e->mem_obj != NULL); debug(20, 3) ("storeSwapInStart: Opening fileno %08X\n", e->swap_filen); - sc->swapin_sio = storeOpen(e, storeSwapInFileNotify, storeSwapInFileClosed, - sc); - cbdataLock(sc->swapin_sio); + sio = storeOpen(e, storeSwapInFileNotify, storeSwapInFileClosed, sc); + sc->swapin_sio = cbdataReference(sio); } static void @@ -73,8 +73,7 @@ storeSwapInFileClosed(void *data, int errflag, storeIOState * sio) STCB *callback; debug(20, 3) ("storeSwapInFileClosed: sio=%p, errflag=%d\n", sio, errflag); - cbdataUnlock(sio); - sc->swapin_sio = NULL; + cbdataReferenceDone(sc->swapin_sio); if ((callback = sc->callback)) { assert(errflag <= 0); sc->callback = NULL; diff --git a/src/store_swapout.cc b/src/store_swapout.cc index 04974ffb31..b29b66804e 100644 --- a/src/store_swapout.cc +++ b/src/store_swapout.cc @@ -1,6 +1,6 @@ /* - * $Id: store_swapout.cc,v 1.86 2002/04/13 14:16:04 hno Exp $ + * $Id: store_swapout.cc,v 1.87 2002/04/13 23:07:51 hno Exp $ * * DEBUG: section 20 Storage Manager Swapout Functions * AUTHOR: Duane Wessels @@ -49,6 +49,7 @@ storeSwapOutStart(StoreEntry * e) int swap_hdr_sz = 0; tlv *tlv_list; char *buf; + storeIOState *sio; assert(mem); /* Build the swap metadata, so the filesystem will know how much * metadata there is to store @@ -63,7 +64,8 @@ storeSwapOutStart(StoreEntry * e) /* Create the swap file */ c = cbdataAlloc(generic_cbdata); c->data = e; - mem->swapout.sio = storeCreate(e, storeSwapOutFileNotify, storeSwapOutFileClosed, c); + sio = storeCreate(e, storeSwapOutFileNotify, storeSwapOutFileClosed, c); + mem->swapout.sio = cbdataReference(sio); if (NULL == mem->swapout.sio) { e->swap_status = SWAPOUT_NONE; cbdataFree(c); @@ -77,7 +79,6 @@ storeSwapOutStart(StoreEntry * e) e->swap_filen = mem->swapout.sio->swap_filen; e->swap_dirn = mem->swapout.sio->swap_dirn; /* write out the swap metadata */ - cbdataLock(mem->swapout.sio); storeWrite(mem->swapout.sio, buf, mem->swap_hdr_sz, 0, xfree); } @@ -327,8 +328,7 @@ storeSwapOutFileClosed(void *data, int errflag, storeIOState * sio) statCounter.swap.outs++; } debug(20, 3) ("storeSwapOutFileClosed: %s:%d\n", __FILE__, __LINE__); - mem->swapout.sio = NULL; - cbdataUnlock(sio); + cbdataReferenceDone(mem->swapout.sio); storeUnlockObject(e); } diff --git a/src/structs.h b/src/structs.h index 2b4b7cfa8b..086759cd21 100644 --- a/src/structs.h +++ b/src/structs.h @@ -1,6 +1,6 @@ /* - * $Id: structs.h,v 1.415 2002/04/07 03:35:30 hno Exp $ + * $Id: structs.h,v 1.416 2002/04/13 23:07:51 hno Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -1432,6 +1432,9 @@ struct _store_client { char *copy_buf; STCB *callback; void *callback_data; +#if STORE_CLIENT_LIST_DEBUG + void *owner; +#endif StoreEntry *entry; /* ptr to the parent StoreEntry, argh! */ storeIOState *swapin_sio; struct { diff --git a/src/tunnel.cc b/src/tunnel.cc index a994497b1f..0d20b717bb 100644 --- a/src/tunnel.cc +++ b/src/tunnel.cc @@ -1,6 +1,6 @@ /* - * $Id: tunnel.cc,v 1.118 2001/10/29 16:06:31 hno Exp $ + * $Id: tunnel.cc,v 1.119 2002/04/13 23:07:51 hno Exp $ * * DEBUG: section 26 Secure Sockets Layer Proxy * AUTHOR: Duane Wessels @@ -211,7 +211,7 @@ sslReadServer(int fd, void *data) kb_incr(&statCounter.server.other.kbytes_in, len); sslState->server.len += len; } - cbdataLock(sslState); + cbdataInternalLock(sslState); /* ??? should be locked by the caller... */ if (len < 0) { debug(50, ignoreErrno(errno) ? 3 : 1) ("sslReadServer: FD %d: read failure: %s\n", fd, xstrerror()); @@ -220,9 +220,9 @@ sslReadServer(int fd, void *data) } else if (len == 0) { comm_close(sslState->server.fd); } - if (cbdataValid(sslState)) + if (cbdataReferenceValid(sslState)) sslSetSelect(sslState); - cbdataUnlock(sslState); + cbdataInternalUnlock(sslState); /* ??? */ } /* Read from client side and queue it for writing to the server */ @@ -245,7 +245,7 @@ sslReadClient(int fd, void *data) kb_incr(&statCounter.client_http.kbytes_in, len); sslState->client.len += len; } - cbdataLock(sslState); + cbdataInternalLock(sslState); /* ??? should be locked by the caller... */ if (len < 0) { int level = 1; #ifdef ECONNRESET @@ -261,9 +261,9 @@ sslReadClient(int fd, void *data) } else if (len == 0) { comm_close(fd); } - if (cbdataValid(sslState)) + if (cbdataReferenceValid(sslState)) sslSetSelect(sslState); - cbdataUnlock(sslState); + cbdataInternalUnlock(sslState); /* ??? */ } /* Writes data from the client buffer to the server side */ @@ -293,16 +293,16 @@ sslWriteServer(int fd, void *data) sslState->client.len); } } - cbdataLock(sslState); + cbdataInternalLock(sslState); /* ??? should be locked by the caller... */ if (len < 0) { debug(50, ignoreErrno(errno) ? 3 : 1) ("sslWriteServer: FD %d: write failure: %s.\n", fd, xstrerror()); if (!ignoreErrno(errno)) comm_close(fd); } - if (cbdataValid(sslState)) + if (cbdataReferenceValid(sslState)) sslSetSelect(sslState); - cbdataUnlock(sslState); + cbdataInternalUnlock(sslState); /* ??? */ } /* Writes data from the server buffer to the client side */ @@ -334,16 +334,16 @@ sslWriteClient(int fd, void *data) sslState->server.len); } } - cbdataLock(sslState); + cbdataInternalLock(sslState); /* ??? should be locked by the caller... */ if (len < 0) { debug(50, ignoreErrno(errno) ? 3 : 1) ("sslWriteClient: FD %d: write failure: %s.\n", fd, xstrerror()); if (!ignoreErrno(errno)) comm_close(fd); } - if (cbdataValid(sslState)) + if (cbdataReferenceValid(sslState)) sslSetSelect(sslState); - cbdataUnlock(sslState); + cbdataInternalUnlock(sslState); /* ??? */ } static void diff --git a/src/urn.cc b/src/urn.cc index 51fb68bb16..511fad2ad8 100644 --- a/src/urn.cc +++ b/src/urn.cc @@ -1,6 +1,6 @@ /* - * $Id: urn.cc,v 1.69 2002/02/26 15:48:16 adrian Exp $ + * $Id: urn.cc,v 1.70 2002/04/13 23:07:52 hno Exp $ * * DEBUG: section 52 URN Parsing * AUTHOR: Kostas Anagnostakis @@ -207,12 +207,11 @@ urnHandleReply(void *data, char *unused_buf, ssize_t size) /* Handle reqofs being bigger than normal */ if (urnState->reqofs >= URN_REQBUF_SZ) { - goto error; + goto error; } - /* If we haven't received the entire object (urn), copy more */ if (urlres_e->store_status == STORE_PENDING && - urnState->reqofs < URN_REQBUF_SZ) { + urnState->reqofs < URN_REQBUF_SZ) { storeClientCopy(urnState->sc, urlres_e, urnState->reqofs, URN_REQBUF_SZ, @@ -303,7 +302,7 @@ urnHandleReply(void *data, char *unused_buf, ssize_t size) safe_free(urls); /* mb was absorbed in httpBodySet call, so we must not clean it */ storeUnregister(urnState->sc, urlres_e, urnState); -error: + error: storeUnlockObject(urlres_e); storeUnlockObject(urnState->entry); requestUnlink(urnState->request); -- 2.39.5