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
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
[ --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,
<article>
<title>Squid Programmers Guide</title>
<author>Squid Developers</author>
-<date>$Id: prog-guide.sgml,v 1.48 2002/04/06 08:49:22 adrian Exp $</date>
+<date>$Id: prog-guide.sgml,v 1.49 2002/04/13 23:07:47 hno Exp $</date>
<abstract>
Squid is a WWW Cache application developed by the National Laboratory
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';
<P>
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.
+
+ <P>
+ 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.
+
+<sect1>API
+
+<sect2>CBDATA_TYPE
+
+ <P>
+<verb>
+ CBDATA_TYPE(datatype);
+</verb>
+
+ <P>
+ 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.
+
+<sect2>CBDATA_GLOBAL_TYPE
+
+ <P>
+<verb>
+ /* Module header file */
+ external CBDATA_GLOBAL_TYPE(datatype);
+
+ /* Module main C file */
+ CBDATA_GLOBAL_TYPE(datatype);
+</verb>
+
+ <P>
+ Defines a global cbdata type that can be referenced anywhere in
+ the code.
+
+<sect2>CBDATA_INIT_TYPE
+
+ <P>
+<verb>
+ CBDATA_INIT_TYPE(datatype);
+ /* or */
+ CBDATA_INIT_TYPE_FREECB(datatype, FREE *freehandler);
+</verb>
+
+ <P>
+ Initializes the cbdatatype. Must be called prior to the first use of
+ cbdataAlloc() for the type.
+
+ <P>
+ The freehandler is called when the last known reference to a
+ allocated entry goes away.
+
+<sect2>cbdataAlloc
+
+ <P>
+<verb>
+ pointer = cbdataAlloc(datatype);
+</verb>
+
+ <P>
+ Allocates a new entry of a registered cbdata type.
+
+<sect2>cbdataFree
+
+ <P>
+<verb>
+ cbdataFree(pointer);
+</verb>
+
+ <P>
+ Frees a entry allocated by cbdataAlloc().
+
+ <P>
+ 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.
+
+<sect2>cbdataReference
+
+ <P>
+<verb>
+ reference = cbdataReference(pointer);
+</verb>
+
+ <P>
+ 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().
+
+ <P>
+ 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 *".
+
+<sect2>cbdataReferenceDone
+
+ <P>
+<verb>
+ cbdataReferenceDone(reference);
+</verb>
+
+ <P>
+ Removes a reference created by cbdataReference().
+
+ <P>
+ Note: The reference variable will be automatically cleared to NULL.
+
+<sect2>cbdataReferenceValid
+
+ <P>
+<verb>
+ if (cbdataReferenceValid(reference)) {
+ ...
+ }
+</verb>
+
+ <P>
+ cbdataReferenceValid() returns false if a reference is stale (refers to a
+ entry freed by cbdataFree).
+
+<sect2>cbdataReferenceValidDone
+
+ <P>
+<verb>
+ void *pointer;
+ bool cbdataReferenceValidDone(reference, &pointer);
+</verb>
+
+ <P>
+ Removes a reference created by cbdataReference() and checks
+ it for validity.
+
+ <P>
+ Meant to be used on the last dereference
+
+<verb>
+ void *cbdata;
+ ...
+ if (cbdataReferenceValidDone(reference, &cbdata)) != NULL)
+ callback(..., cbdata);
+</verb>
+
+ <P>
+ Note: The reference variable will be automatically cleared to NULL.
+
+<sect1>Examples
+
+ <P>
+ For a blocking operation
with callback functions, the normal sequence of events is as
follows:
<verb>
operation executes elsewhere, and is freed when the operation
completes. The normal sequence of events is:
<verb>
+ /* 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);
+ }
</verb>
<P>
With this scheme, nothing bad happens if <tt/cbdataFree/ gets called
- before <tt/cbdataUnlock/:
+ before fooOperantionComplete(...).
<verb>
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, ....);
</verb>
In this case, when <tt/cbdataFree/ is called before
- <tt/cbdataUnlock/, the callback_data gets marked as invalid. Before
- executing the callback function, <tt/cbdataValid/ will return 0
- and callback_func is never executed. When <tt/cbdataUnlock/ gets
+ <tt/cbdataReferenceValidDone/, the callback_data gets marked as invalid.
+ Before executing the callback function, <tt/cbdataReferenceValidDone/ will return 0
+ and callback_func is never executed. When <tt/cbdataReferenceValidDone/ gets
called, it notices that the callback_data is invalid and will
then call <tt/cbdataFree/.
/*
- * $Id: MemBuf.cc,v 1.29 2002/02/13 19:34:02 hno Exp $
+ * $Id: MemBuf.cc,v 1.30 2002/04/13 23:07:48 hno Exp $
*
* DEBUG: section 59 auto-growing Memory Buffer with printf
* AUTHOR: Alex Rousskov
assert(mb->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;
}
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;
}
/*
- * $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
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);
#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;
}
* 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);
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) {
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);
}
* 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);
}
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;
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);
}
/*
- * $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
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 */
asStateFree(asState);
return;
}
-
/*
* Next, attempt to parse our request
* Remembering that the actual buffer size is retsize + reqofs!
*/
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,
/*
- * $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
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 : "<NULL>");
if (reply) {
if ((t = strchr(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;
}
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;
/*
- * $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
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 : "<NULL>");
if (reply) {
if ((t = strchr(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);
}
}
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);
/*
- * $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
{
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;
}
{
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;
ntlm_user_t *ntlm_user;
ntlm_request_t *ntlm_request;
debug(29, 9) ("authenticateNTLMHandleReply: Helper: '%p' {%s}\n", lastserver, reply ? reply : "<NULL>");
- 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;
* 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;
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;
/* 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);
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 */
/*
- * $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
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)
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);
}
/*
- * $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
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);
/*
- * $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
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;
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);
/*
- * $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
* 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;
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) {
}
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;
}
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);
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",
}
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);
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;
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);
}
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");
}
/*
- * $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
* 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;
}
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);
/*
- * $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
{
CommWriteStateData *CommWriteState = fd_table[fd].rwstate;
CWCB *callback = NULL;
- void *data;
+ void *cbdata;
fd_table[fd].rwstate = NULL;
if (CommWriteState == NULL)
return;
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);
}
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);
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
{
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);
}
{
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);
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;
}
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 */
}
}
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 */
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
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
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);
}
{
int fd;
fde *F = NULL;
- PF *callback;
for (fd = 0; fd <= Biggest_FD; fd++) {
F = &fd_table[fd];
if (!F->flags.open)
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);
/*
- * $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
*
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
/*
- * $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
*
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;
}
/*
- * $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/
#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
/*
- * $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 <david@luyer.net>
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);
/*
- * $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
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;
} 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)
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 */
F->disk.write_q_tail = wq;
}
if (!F->flags.write_daemon) {
- cbdataLock(F->disk.wrt_handle_data);
diskHandleWrite(fd, NULL);
}
}
} 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);
}
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);
}
/*
- * $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
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,
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);
}
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);
}
}
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);
}
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);
}
/*
- * $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
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) {
if (event->arg != arg)
continue;
*E = event->next;
- if (NULL != event->arg)
- cbdataUnlock(event->arg);
+ cbdataReferenceDone(event->arg);
memFree(event, MEM_EVENT);
return;
}
eventRun(void)
{
struct ev_entry *event = NULL;
- EVH *func;
- void *arg;
int weight = 0;
if (NULL == tasks)
return;
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);
}
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;
}
}
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;
/*
- * $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
static void
fwdServerFree(FwdServer * fs)
{
- if (fs->peer)
- cbdataUnlock(fs->peer);
+ cbdataReferenceDone(fs->peer);
memFree(fs, MEM_FWD_SERVER);
}
/*
- * $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
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);
}
else
FqdncacheStats.hits++;
f->handler = handler;
- f->handlerData = handlerData;
- cbdataLock(handlerData);
+ f->handlerData = cbdataReference(handlerData);
fqdncacheCallback(f);
return;
}
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;
/*
- * $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 <pete@demon.net>
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);
aioCancel(int fd)
{
squidaio_ctrl_t *curr;
- AIOCB *done_handler;
- void *their_data;
dlink_node *m, *next;
assert(initialised);
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);
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;
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);
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;
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);
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);
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);
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);
{
squidaio_result_t *resultp;
squidaio_ctrl_t *ctrlp;
- AIOCB *done_handler;
- void *their_data;
int retval = 0;
assert(initialised);
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)
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);
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);
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;
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);
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);
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)
* 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"
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;
/* 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);
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;
/* 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);
DRCB *rc;
DWCB *wc;
FREE *freefunc;
- void *callback_data;
+ void *cbdata;
void *buf;
int fd;
async_queue_entry_t *aqe;
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;
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);
}
/*
- * $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
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;
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;
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;
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;
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);
}
/*
- * $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
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;
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;
}
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;
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;
}
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");
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);
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;
}
{
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) {
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,
* -- adrian
*/
xmemcpy(their_buf, sbuf, len); /* yucky copy */
- callback(their_data, their_buf, len);
+ callback(cbdata, their_buf, len);
}
}
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);
/*
* 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);
}
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);
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);
}
/*
/*
- * $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
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;
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;
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;
{
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",
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
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);
}
/*
- * $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
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;
/*
- * $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/
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 */
/*
- * $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?
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);
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);
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
return;
}
r->callback = callback;
- r->data = data;
+ r->data = cbdataReference(data);
if (buf != NULL) {
r->buf = xstrdup(buf);
r->placeholder = 0;
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
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;
}
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);
}
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;
}
}
if (srv->data != NULL)
memPoolFree(hlp->datapool, srv->data);
- cbdataUnlock(srv->parent);
+ cbdataReferenceDone(srv->parent);
cbdataFree(srv);
}
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);
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);
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);
/* 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");
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;
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;
static void
helperRequestFree(helper_request * r)
{
- cbdataUnlock(r->data);
+ cbdataReferenceDone(r->data);
xfree(r->buf);
memFree(r, MEM_HELPER_REQUEST);
}
static void
helperStatefulRequestFree(helper_stateful_request * r)
{
- cbdataUnlock(r->data);
+ cbdataReferenceDone(r->data);
xfree(r->buf);
memFree(r, MEM_HELPER_STATEFUL_REQUEST);
}
/*
- * $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
* 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");
/*
- * $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
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);
}
}
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) {
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;
}
/*
- * $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
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);
}
else
IpcacheStats.hits++;
i->handler = handler;
- i->handlerData = handlerData;
- cbdataLock(handlerData);
+ i->handlerData = cbdataReference(handlerData);
ipcacheCallback(i);
return;
}
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;
/*
- * $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
}
static void
-memBufStats(StoreEntry *sentry)
+memBufStats(StoreEntry * sentry)
{
storeAppendPrintf(sentry, "Large buffers: %d (%d KB)\n",
HugeBufCountMeter.level,
{
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;
pool->label, memPoolInUseCount(pool), pool->obj_size,
toKB(pool->obj_size * pool->meter.inuse.level));
}
+
#endif
void
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);
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);
}
/*
- * $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
}
safe_free(p->host);
#if USE_CACHE_DIGESTS
- if (p->digest) {
- PeerDigest *pd = p->digest;
- p->digest = NULL;
- cbdataUnlock(pd);
- }
+ cbdataReferenceDone(p->digest);
#endif
}
peerNoteDigestGone(peer * p)
{
#if USE_CACHE_DIGESTS
- if (p->digest) {
- PeerDigest *pd = p->digest;
- p->digest = NULL;
- cbdataUnlock(pd);
- }
+ cbdataReferenceDone(p->digest);
#endif
}
/*
- * $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
#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 {
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;
/* 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))) {
}
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 .. */
ex->used += rec_sz;
size -= rec_sz;
p += rec_sz;
- nused++;
+ nused++;
}
/*
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);
requestUnlink(ex->r);
storeUnregister(ex->sc, ex->e, ex);
storeUnlockObject(ex->e);
- cbdataUnlock(ex->p);
+ cbdataReferenceDone(ex->p);
cbdataFree(ex);
}
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);
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);
/*
- * $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
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)
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)
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);
else
xfree(p->fds);
xfree(p->hash.key);
- memPoolFree(pconn_data_pool, p);
+ cbdataFree(p);
}
static 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",
/*
- * $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
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 */
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);
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;
}
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;
/* 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);
}
/* 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);
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);
}
} 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? */
fetch->state = DIGEST_READ_DONE;
} else {
fetch->state = DIGEST_READ_HEADERS;
- }
+ }
} else {
/* need more data, do we have space? */
if (size >= SM_PAGE_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");
}
/* 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");
}
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");
}
const char *host = "<unknown>"; /* 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 */
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
/* 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";
else
debug(72, 2) ("received valid digest from %s\n", host);
}
- fetch->pd = NULL;
- cbdataUnlock(pd);
+ cbdataReferenceDone(fetch->pd);
}
/* free fetch state structures
fetch->entry = NULL;
fetch->request = NULL;
assert(fetch->pd == NULL);
- cbdataUnlock(fetch);
cbdataFree(fetch);
}
/*
- * $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
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);
}
{
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)
}
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);
}
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;
}
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;
/*
- * $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/
*/
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);
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);
/*
* 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 *);
/*
- * $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
redirectHandleReply(void *data, char *reply)
{
redirectStateData *r = data;
- int valid;
char *t;
+ void *cbdata;
debug(29, 5) ("redirectHandleRead: {%s}\n", reply ? reply : "<NULL>");
if (reply) {
if ((t = strchr(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);
}
}
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",
/*
- * $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
*
* directly, so this is a dirty hack!
*/
#if defined(_SQUID_LINUX_)
-# undef CHANGE_FD_SETSIZE
-# define CHANGE_FD_SETSIZE 0
-# include <features.h>
-# if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)
-# if SQUID_MAXFD > DEFAULT_FD_SETSIZE
-# include <bits/types.h>
-# undef __FD_SETSIZE
-# define __FD_SETSIZE SQUID_MAXFD
-# endif
-# endif
+#undef CHANGE_FD_SETSIZE
+#define CHANGE_FD_SETSIZE 0
+#include <features.h>
+#if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)
+#if SQUID_MAXFD > DEFAULT_FD_SETSIZE
+#include <bits/types.h>
+#undef __FD_SETSIZE
+#define __FD_SETSIZE SQUID_MAXFD
+#endif
+#endif
#endif
/*
#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__)
/*
- * $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
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());
} 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 */
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
} 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 */
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 */
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
/*
- * $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
}
#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;
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;
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
}
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");
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;
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;
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);
* 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
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
* 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 */
}
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);
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) {
#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)
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)
/*
- * $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
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 */
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
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;
/*
- * $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
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
/* 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);
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);
}
statCounter.swap.outs++;
}
debug(20, 3) ("storeSwapOutFileClosed: %s:%d\n", __FILE__, __LINE__);
- mem->swapout.sio = NULL;
- cbdataUnlock(sio);
+ cbdataReferenceDone(mem->swapout.sio);
storeUnlockObject(e);
}
/*
- * $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/
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 {
/*
- * $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
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());
} 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 */
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
} 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 */
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 */
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
/*
- * $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
/* 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,
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);