/*
- * $Id: ACLChecklist.cc,v 1.37 2007/05/09 08:31:47 wessels Exp $
+ * $Id: ACLChecklist.cc,v 1.38 2007/05/09 09:07:38 wessels Exp $
*
* DEBUG: section 28 Access Control
* AUTHOR: Duane Wessels
/* get authed here */
/* Note: this fills in auth_user_request when applicable */
- switch (AuthUserRequest::tryToAuthenticateAndSetAuthUser (&auth_user_request, headertype, request, conn(), src_addr)) {
+ /*
+ * DPW 2007-05-08
+ * tryToAuthenticateAndSetAuthUser used to try to lock and
+ * unlock auth_user_request on our behalf, but it was too
+ * ugly and hard to follow. Now we do our own locking here.
+ *
+ * I'm not sure what tryToAuthenticateAndSetAuthUser does when
+ * auth_user_request is set before calling. I'm tempted to
+ * unlock and set it to NULL, but it seems safer to save the
+ * pointer before calling and unlock it afterwards. If the
+ * pointer doesn't change then its a no-op.
+ */
+ AuthUserRequest *old_auth_user_request = auth_user_request;
+ auth_acl_t result = AuthUserRequest::tryToAuthenticateAndSetAuthUser (&auth_user_request, headertype, request, conn(), src_addr);
+ if (auth_user_request)
+ AUTHUSERREQUESTLOCK(auth_user_request, "ACLChecklist");
+ AUTHUSERREQUESTUNLOCK(old_auth_user_request, "old ACLChecklist");
+ switch (result) {
case AUTH_ACL_CANNOT_AUTHENTICATE:
debugs(28, 4, "aclMatchAcl: returning 0 user authenticated but not authorised.");
if (auth_user_request) {
/* the checklist lock */
- auth_user_request->unlock();
+ AUTHUSERREQUESTUNLOCK(auth_user_request, "ACLChecklist");
/* it might have been connection based */
assert(conn() != NULL);
- conn()->auth_user_request = NULL;
+ /*
+ * DPW 2007-05-08
+ * yuck, this make me uncomfortable. why do this here?
+ * ConnStateData will do its own unlocking.
+ */
+ AUTHUSERREQUESTUNLOCK(conn()->auth_user_request, "conn via ACLChecklist");
conn()->auth_type = AUTH_BROKEN;
- auth_user_request = NULL;
}
callback_ = callback;
ACLChecklist::ACLChecklist() : accessList (NULL), my_port (0), request (NULL),
reply (NULL),
- auth_user_request (NULL)
+ auth_user_request (NULL),
#if SQUID_SNMP
- ,snmp_community(NULL)
+ snmp_community(NULL),
#endif
- , callback (NULL),
+ callback (NULL),
callback_data (NULL),
extacl_entry (NULL),
conn_(NULL),
HTTPMSGUNLOCK(reply);
+ /*
+ * DPW 2007-05-08
+ * If this fails, then we'll need a backup UNLOCK call in the
+ * destructor.
+ */
+ assert(auth_user_request == NULL);
+
conn_ = NULL;
cbdataReferenceDone(accessList);
#endif
- checklist->auth_user_request = NULL;
-
return checklist;
}
/* credentials could not be checked either way
* restart the whole process */
/* OR the connection was closed, there's no way to continue */
- checklist->auth_user_request->unlock();
+ AUTHUSERREQUESTUNLOCK(checklist->auth_user_request, "ProxyAuthLookup");
if (checklist->conn() != NULL) {
- checklist->conn()->auth_user_request = NULL;
+ AUTHUSERREQUESTUNLOCK(checklist->conn()->auth_user_request, "conn via ProxyAuthLookup"); // DPW discomfort
checklist->conn()->auth_type = AUTH_BROKEN;
}
-
- checklist->auth_user_request = NULL;
}
checklist->asyncInProgress(false);
ACLProxyAuth::checkAuthForCaching(ACLChecklist *checklist)const
{
/* for completeness */
-
- checklist->auth_user_request->lock()
-
- ;
/* consistent parameters ? */
assert(authenticateUserAuthenticated(checklist->auth_user_request));
-
/* this check completed */
- checklist->auth_user_request->unlock();
}
/*
- * $Id: AuthConfig.cc,v 1.3 2007/04/28 22:26:37 hno Exp $
+ * $Id: AuthConfig.cc,v 1.4 2007/05/09 09:07:38 wessels Exp $
*
* DEBUG: section 29 Authenticator
* AUTHOR: Robert Collins
return NULL;
}
- assert (config != NULL);
-
AuthUserRequest *result = config->decode (proxy_auth);
- /* and lock for the callers instance */
-
- if (result != NULL)
- result->lock()
- ;
+ /*
+ * DPW 2007-05-08
+ * Do not lock the AuthUserRequest on the caller's behalf.
+ * Callers must manage their own locks.
+ */
return result;
}
/*
- * $Id: AuthUserRequest.cc,v 1.15 2007/05/09 07:36:24 wessels Exp $
+ * $Id: AuthUserRequest.cc,v 1.16 2007/05/09 09:07:38 wessels Exp $
*
* DO NOT MODIFY NEXT 2 LINES:
* arch-tag: 6803fde1-d5a2-4c29-9034-1c0c9f650eb4
* callback mechanism like the acl testing routines that will send a 40[1|7] to
* the client when rv==AUTH_ACL_CHALLENGE, and will communicate with
* the authenticateStart routine for rv==AUTH_ACL_HELPER
+ *
+ * Caller is responsible for locking and unlocking their *auth_user_request!
*/
auth_acl_t
if (conn != NULL) {
conn->auth_type = AUTH_UNKNOWN;
-
- if (conn->auth_user_request)
- conn->auth_user_request->unlock();
-
- conn->auth_user_request = NULL;
- }
-
- if (*auth_user_request) {
- /* unlock the ACL lock */
- (*auth_user_request)->unlock();
- auth_user_request = NULL;
+ AUTHUSERREQUESTUNLOCK(conn->auth_user_request, "conn");
}
+ *auth_user_request = NULL;
return AUTH_ACL_CHALLENGE;
}
* authenticateAuthenticate
*/
assert(*auth_user_request == NULL);
- /* unlock the conn lock on the auth_user_request */
- conn->auth_user_request->unlock();
- /* mark the conn as non-authed. */
- conn->auth_user_request = NULL;
+ AUTHUSERREQUESTUNLOCK(conn->auth_user_request, "conn");
/* Set the connection auth type */
conn->auth_type = AUTH_UNKNOWN;
}
"' to '" << proxy_auth << "' (client " <<
inet_ntoa(src_addr) << ")");
- conn->auth_user_request->unlock();
- conn->auth_user_request = NULL;
+ AUTHUSERREQUESTUNLOCK(conn->auth_user_request, "conn");
conn->auth_type = AUTH_UNKNOWN;
}
}
/* beginning of a new request check */
debugs(29, 4, "authenticateAuthenticate: no connection authentication type");
- if (!authenticateValidateUser(*auth_user_request =
- AuthConfig::CreateAuthUser(proxy_auth))) {
+ *auth_user_request = AuthConfig::CreateAuthUser(proxy_auth);
+ if (!authenticateValidateUser(*auth_user_request)) {
if (*auth_user_request == NULL)
return AUTH_ACL_CHALLENGE;
* the user */
if ((*auth_user_request)->username()) {
- /* lock the user for the request structure link */
-
- (*auth_user_request)->lock()
-
- ;
request->auth_user_request = *auth_user_request;
+ AUTHUSERREQUESTLOCK(request->auth_user_request, "request");
}
- /* unlock the ACL reference granted by ...createAuthUser. */
- (*auth_user_request)->unlock();
-
*auth_user_request = NULL;
-
return AUTH_ACL_CHALLENGE;
}
/* the user_request comes prelocked for the caller to createAuthUser (us) */
} else if (request->auth_user_request) {
*auth_user_request = request->auth_user_request;
- /* lock the user request for this ACL processing */
-
- (*auth_user_request)->lock()
-
- ;
} else {
assert (conn != NULL);
-
- if (conn->auth_user_request != NULL) {
+ if (conn->auth_user_request) {
*auth_user_request = conn->auth_user_request;
- /* lock the user request for this ACL processing */
-
- (*auth_user_request)->lock()
-
- ;
} else {
/* failed connection based authentication */
debugs(29, 4, "authenticateAuthenticate: Auth user request " <<
conn->auth_user_request << " conn type " <<
conn->auth_type << " authentication failed.");
- (*auth_user_request)->unlock();
*auth_user_request = NULL;
return AUTH_ACL_CHALLENGE;
}
case 1:
- if (!request->auth_user_request) {
-
- (*auth_user_request)->lock()
-
- ;
+ if (NULL == request->auth_user_request) {
request->auth_user_request = *auth_user_request;
+ AUTHUSERREQUESTLOCK(request->auth_user_request, "request");
}
/* fallthrough to -2 */
case -2:
- /* this ACL check is finished. Unlock. */
- (*auth_user_request)->unlock();
-
+ /* this ACL check is finished. */
*auth_user_request = NULL;
-
return AUTH_ACL_CHALLENGE;
case -1:
if (!authenticateUserAuthenticated(*auth_user_request)) {
if ((*auth_user_request)->username()) {
if (!request->auth_user_request) {
- /* lock the user for the request structure link */
-
- (*auth_user_request)->lock()
-
- ;
request->auth_user_request = *auth_user_request;
+ AUTHUSERREQUESTLOCK(request->auth_user_request, "request");
}
}
- /* this ACL check is finished. Unlock. */
- (*auth_user_request)->unlock();
-
*auth_user_request = NULL;
-
return AUTH_ACL_CHALLENGE;
}
}
/* copy username to request for logging on client-side */
/* the credentials are correct at this point */
- if (!request->auth_user_request)
- {
- /* lock the user for the request structure link */
-
- (*auth_user_request)->lock()
-
- ;
+ if (NULL == request->auth_user_request) {
request->auth_user_request = *auth_user_request;
-
+ AUTHUSERREQUESTLOCK(request->auth_user_request, "request");
authenticateAuthUserRequestSetIp(*auth_user_request, src_addr);
}
- /* Unlock the request - we've authenticated it */
- (*auth_user_request)->unlock();
-
return AUTH_AUTHENTICATED;
}
if (!request->auth_user_request && t->lastReply == AUTH_AUTHENTICATED) {
request->auth_user_request = t;
- t->lock();
+ AUTHUSERREQUESTLOCK(request->auth_user_request, "request");
}
return t->lastReply;
}
void
-AuthUserRequest::lock()
+AuthUserRequest::_lock()
{
- debugs(29, 9, "AuthUserRequest::lock: auth_user request '" << this << "' (" << references << " references).");
assert(this);
+ debugs(29, 9, "AuthUserRequest::lock: auth_user request '" << this << " " << references << "->" << references+1);
++references;
}
void
-AuthUserRequest::unlock()
+AuthUserRequest::_unlock()
{
- debugs(29, 9, "AuthUserRequest::unlock: auth_user request '" << this << "' (" << references << " references) .");
assert(this != NULL);
if (references > 0) {
+ debugs(29, 9, "AuthUserRequest::unlock: auth_user request '" << this << " " << references << "->" << references-1);
--references;
} else {
debugs(29, 1, "Attempt to lower Auth User request " << this << " refcount below 0!");
/*
- * $Id: AuthUserRequest.h,v 1.5 2007/05/09 07:36:24 wessels Exp $
+ * $Id: AuthUserRequest.h,v 1.6 2007/05/09 09:07:38 wessels Exp $
*
* DO NOT MODIFY NEXT 2 LINES:
* arch-tag: 674533af-8b21-4641-b71a-74c4639072a0
char const * getDenyMessage ();
size_t refCount() const;
-
- void lock ()
-
- ;
- void unlock ();
+ void _lock (); // please use AUTHUSERREQUESTLOCK()
+ void _unlock (); // please use AUTHUSERREQUESTUNLOCK()
char const *username() const;
extern int authenticateUserAuthenticated(AuthUserRequest *);
extern int authenticateValidateUser(AuthUserRequest *);
+#if 0
+#define AUTHUSERREQUESTUNLOCK(a,b) if(a){(a)->_unlock();debugs(0,0,HERE << "auth_user_request " << a << " was unlocked for " << b); (a)=NULL;}
+#define AUTHUSERREQUESTLOCK(a,b) { (a)->_lock(); debugs(0,0,HERE << "auth_user_request " << a << " was locked for " << b); }
+#endif
+#define AUTHUSERREQUESTUNLOCK(a,b) if(a){(a)->_unlock();(a)=NULL;}
+#define AUTHUSERREQUESTLOCK(a,b) (a)->_lock()
+
+
#endif /* SQUID_AUTHUSERREQUEST_H */
/*
- * $Id: HttpRequest.cc,v 1.73 2007/04/28 22:26:37 hno Exp $
+ * $Id: HttpRequest.cc,v 1.74 2007/05/09 09:07:38 wessels Exp $
*
* DEBUG: section 73 HTTP Request
* AUTHOR: Duane Wessels
// points to a pipe that is owned and initiated by another object.
body_pipe = NULL;
- if (auth_user_request) {
- auth_user_request->unlock();
- auth_user_request = NULL;
- }
+ AUTHUSERREQUESTUNLOCK(auth_user_request, "request");
safe_free(canonical);
/*
- * $Id: auth_digest.cc,v 1.54 2007/05/09 07:36:28 wessels Exp $
+ * $Id: auth_digest.cc,v 1.55 2007/05/09 09:07:39 wessels Exp $
*
* DEBUG: section 29 Authenticator
* AUTHOR: Robert Collins
replyData->handler(cbdata, NULL);
//we know replyData->auth_user_request != NULL, or we'd have asserted
- replyData->auth_user_request->unlock();
-
- replyData->auth_user_request=NULL;
+ AUTHUSERREQUESTUNLOCK(replyData->auth_user_request, "replyData");
cbdataFree(replyData);
}
r->handler = handler;
r->data = cbdataReference(data);
r->auth_user_request = this;
-
- lock()
-
- ;
-
+ AUTHUSERREQUESTLOCK(r->auth_user_request, "r");
snprintf(buf, 8192, "\"%s\":\"%s\"\n", digest_user->username(), realm);
helperSubmit(digestauthenticators, buf, authenticateDigestHandleReply, r);
/*
- * $Id: auth_negotiate.cc,v 1.17 2007/05/09 08:07:23 wessels Exp $
+ * $Id: auth_negotiate.cc,v 1.18 2007/05/09 09:07:40 wessels Exp $
*
* DEBUG: section 29 Negotiate Authenticator
* AUTHOR: Robert Collins, Henrik Nordstrom, Francesco Chemolli
static void
authenticateStateFree(authenticateStateData * r)
{
+ AUTHUSERREQUESTUNLOCK(r->auth_user_request, "r");
cbdataFree(r);
}
r = cbdataAlloc(authenticateStateData);
r->handler = handler;
r->data = cbdataReference(data);
- r->auth_user_request = this;
-
- lock()
-
- ;
+ AUTHUSERREQUESTLOCK(r->auth_user_request, "r");
if (auth_state == AUTHENTICATE_STATE_INITIAL) {
snprintf(buf, 8192, "YR %s\n", client_blob); //CHECKME: can ever client_blob be 0 here?
} else {
/* clear any connection related authentication details */
void
-AuthNegotiateUserRequest::onConnectionClose(ConnStateData *connection)
+AuthNegotiateUserRequest::onConnectionClose(ConnStateData *conn)
{
- assert(connection != NULL);
+ assert(conn != NULL);
- debugs(29, 8, "AuthNegotiateUserRequest::onConnectionClose: closing connection '" << connection << "' (this is '" << this << "')");
+ debugs(29, 8, "AuthNegotiateUserRequest::onConnectionClose: closing connection '" << conn << "' (this is '" << this << "')");
- if (connection->auth_user_request == NULL) {
+ if (conn->auth_user_request == NULL) {
debugs(29, 8, "AuthNegotiateUserRequest::onConnectionClose: no auth_user_request");
return;
}
authenticateNegotiateReleaseServer(this);
/* unlock the connection based lock */
- debugs(29, 9, "AuthNegotiateUserRequest::onConnectionClose: Unlocking auth_user from the connection '" << connection << "'.");
-
- /* This still breaks the abstraction, but is at least read only now.
- * If needed, this could be ignored, as the conn deletion will also unlock
- * the auth user request.
- */
- unlock();
-
- connection->auth_user_request = NULL;
+ debugs(29, 9, "AuthNegotiateUserRequest::onConnectionClose: Unlocking auth_user from the connection '" << conn << "'.");
+ AUTHUSERREQUESTUNLOCK(conn->auth_user_request, "conn");
}
/*
safe_free(client_blob);
client_blob=xstrdup(blob);
conn->auth_type = AUTH_NEGOTIATE;
+ assert(conn->auth_user_request == NULL);
conn->auth_user_request = this;
- conn = conn;
-
- lock()
-
- ;
+ AUTHUSERREQUESTLOCK(conn->auth_user_request, "conn");
return;
break;
/*
- * $Id: auth_ntlm.cc,v 1.67 2007/05/09 08:14:09 wessels Exp $
+ * $Id: auth_ntlm.cc,v 1.68 2007/05/09 09:07:43 wessels Exp $
*
* DEBUG: section 29 NTLM Authenticator
* AUTHOR: Robert Collins, Henrik Nordstrom, Francesco Chemolli
static void
authenticateStateFree(authenticateStateData * r)
{
+ AUTHUSERREQUESTUNLOCK(r->auth_user_request, "r");
cbdataFree(r);
}
ntlm_user->username(blob);
auth_user_request->denyMessage("Login successful");
safe_free(ntlm_request->server_blob);
- authenticateNTLMReleaseServer(ntlm_request);
- ntlm_request->auth_state = AUTHENTICATE_STATE_DONE;
result = S_HELPER_RELEASE;
debugs(29, 4, "authenticateNTLMHandleReply: Successfully validated user via NTLM. Username '" << blob << "'");
r->handler = handler;
r->data = cbdataReference(data);
r->auth_user_request = this;
+ AUTHUSERREQUESTLOCK(r->auth_user_request, "r");
- lock()
-
- ;
if (auth_state == AUTHENTICATE_STATE_INITIAL) {
snprintf(buf, 8192, "YR %s\n", client_blob); //CHECKME: can ever client_blob be 0 here?
} else {
* Let's see what happens, might segfault in helperStatefulReleaseServer
* if it does. I leave it like this not to cover possibly problematic
* code-paths. Kinkie */
- helperStatefulReleaseServer(ntlm_request->authserver);
- ntlm_request->authserver = NULL;
+ /* DPW 2007-05-07
+ * yes, it is possible */
+ if (ntlm_request->authserver) {
+ helperStatefulReleaseServer(ntlm_request->authserver);
+ ntlm_request->authserver = NULL;
+ }
}
/* clear any connection related authentication details */
void
-AuthNTLMUserRequest::onConnectionClose(ConnStateData *connection)
+AuthNTLMUserRequest::onConnectionClose(ConnStateData *conn)
{
- assert(connection != NULL);
+ assert(conn != NULL);
- debugs(29, 8, "AuthNTLMUserRequest::onConnectionClose: closing connection '" << connection << "' (this is '" << this << "')");
+ debugs(29, 8, "AuthNTLMUserRequest::onConnectionClose: closing connection '" << conn << "' (this is '" << this << "')");
- if (connection->auth_user_request == NULL) {
+ if (conn->auth_user_request == NULL) {
debugs(29, 8, "AuthNTLMUserRequest::onConnectionClose: no auth_user_request");
return;
}
authenticateNTLMReleaseServer(this);
/* unlock the connection based lock */
- debugs(29, 9, "AuthNTLMUserRequest::onConnectionClose: Unlocking auth_user from the connection '" << connection << "'.");
+ debugs(29, 9, "AuthNTLMUserRequest::onConnectionClose: Unlocking auth_user from the connection '" << conn << "'.");
- /* This still breaks the abstraction, but is at least read only now.
- * If needed, this could be ignored, as the conn deletion will also unlock
- * the auth user request.
- */
- unlock();
-
- connection->auth_user_request = NULL;
+ AUTHUSERREQUESTUNLOCK(conn->auth_user_request, "conn");
}
/*
safe_free(client_blob);
client_blob=xstrdup(blob);
conn->auth_type = AUTH_NTLM;
+ assert(conn->auth_user_request == NULL);
conn->auth_user_request = this;
- conn = conn;
-
- lock()
-
- ;
+ AUTHUSERREQUESTLOCK(conn->auth_user_request, "conn");
return;
break;
/*
- * $Id: client_side.cc,v 1.752 2007/04/30 16:56:09 wessels Exp $
+ * $Id: client_side.cc,v 1.753 2007/05/09 09:07:38 wessels Exp $
*
* DEBUG: section 33 Client-side Routines
* AUTHOR: Duane Wessels
aLogEntry->cache.authuser =
xstrdup(request->auth_user_request->username());
- request->auth_user_request->unlock();
-
- request->auth_user_request = NULL;
+ AUTHUSERREQUESTUNLOCK(request->auth_user_request, "request via clientPrepareLogWithRequestDetails");
}
}
if (isOpen())
close();
- if (auth_user_request)
- auth_user_request->unlock();
-
- auth_user_request = NULL;
+ AUTHUSERREQUESTUNLOCK(auth_user_request, "~conn");
cbdataReferenceDone(port);
/*
- * $Id: client_side_reply.cc,v 1.125 2007/05/09 07:36:24 wessels Exp $
+ * $Id: client_side_reply.cc,v 1.126 2007/05/09 09:07:38 wessels Exp $
*
* DEBUG: section 88 Client-side Reply Routines
* AUTHOR: Robert Collins (Originally Duane Wessels in client_side.c)
void
clientReplyContext::setReplyToError(
err_type err, http_status status, method_t method, char const *uri,
-
struct IN_ADDR *addr, HttpRequest * failedrequest, char *unparsedrequest,
AuthUserRequest * auth_user_request)
{
if (auth_user_request)
{
errstate->auth_user_request = auth_user_request;
-
- errstate->auth_user_request->lock()
-
- ;
+ AUTHUSERREQUESTLOCK(errstate->auth_user_request, "errstate");
}
assert(errstate->callback_data == NULL);
/*
- * $Id: client_side_request.cc,v 1.84 2007/05/08 16:46:37 rousskov Exp $
+ * $Id: client_side_request.cc,v 1.85 2007/05/09 09:07:39 wessels Exp $
*
* DEBUG: section 85 Client-side Request Routines
* AUTHOR: Robert Collins (Originally Duane Wessels in client_side.c)
if (old_request->auth_user_request) {
new_request->auth_user_request = old_request->auth_user_request;
-
- new_request->auth_user_request->lock()
-
- ;
+ AUTHUSERREQUESTLOCK(new_request->auth_user_request, "new request");
}
if (old_request->body_pipe != NULL) {
/*
- * $Id: errorpage.cc,v 1.224 2007/04/30 16:56:09 wessels Exp $
+ * $Id: errorpage.cc,v 1.225 2007/05/09 09:07:39 wessels Exp $
*
* DEBUG: section 4 Error Generation
* AUTHOR: Duane Wessels
wordlistDestroy(&err->ftp.server_msg);
safe_free(err->ftp.request);
safe_free(err->ftp.reply);
-
- if (err->auth_user_request)
- err->auth_user_request->unlock();
-
- err->auth_user_request = NULL;
-
+ AUTHUSERREQUESTUNLOCK(err->auth_user_request, "errstate");
safe_free(err->err_msg);
-
cbdataFree(err);
}
/*
- * $Id: helper.cc,v 1.83 2007/05/07 18:38:40 wessels Exp $
+ * $Id: helper.cc,v 1.84 2007/05/09 09:07:39 wessels Exp $
*
* DEBUG: section 84 Helper process maintenance
* AUTHOR: Harvest Derived?
helperKickQueue(hlp);
}
+/*
+ * DPW 2007-05-08
+ *
+ * helperStatefulOpenServers: create the stateful child helper processes
+ */
void
helperStatefulOpenServers(statefulhelper * hlp)
{
- char *s;
- char *progname;
char *shortname;
- char *procname;
const char *args[HELPER_MAX_ARGS];
char fd_note_buf[FD_DESC_SZ];
- helper_stateful_server *srv;
int nargs = 0;
- int k;
- pid_t pid;
- int rfd;
- int wfd;
- void * hIpc;
- wordlist *w;
if (hlp->cmdline == NULL)
return;
- progname = hlp->cmdline->key;
+ char *progname = hlp->cmdline->key;
+ char *s;
if ((s = strrchr(progname, '/')))
shortname = xstrdup(s + 1);
else
debugs(84, 1, "helperStatefulOpenServers: Starting " << hlp->n_to_start << " '" << shortname << "' processes");
- procname = (char *)xmalloc(strlen(shortname) + 3);
+ char *procname = (char *)xmalloc(strlen(shortname) + 3);
snprintf(procname, strlen(shortname) + 3, "(%s)", shortname);
args[nargs++] = procname;
- for (w = hlp->cmdline->next; w && nargs < HELPER_MAX_ARGS; w = w->next)
+ for (wordlist *w = hlp->cmdline->next; w && nargs < HELPER_MAX_ARGS; w = w->next)
args[nargs++] = w->key;
args[nargs++] = NULL;
assert(nargs <= HELPER_MAX_ARGS);
- for (k = 0; k < hlp->n_to_start; k++) {
+ for (int k = 0; k < hlp->n_to_start; k++) {
getCurrentTime();
- rfd = wfd = -1;
- pid = ipcCreate(hlp->ipc_type,
+ int rfd = -1;
+ int wfd = -1;
+ void * hIpc;
+ pid_t pid = ipcCreate(hlp->ipc_type,
progname,
args,
shortname,
hlp->n_running++;
hlp->n_active++;
CBDATA_INIT_TYPE(helper_stateful_server);
- srv = cbdataAlloc(helper_stateful_server);
+ helper_stateful_server *srv = cbdataAlloc(helper_stateful_server);
srv->hIpc = hIpc;
srv->pid = pid;
srv->flags.reserved = S_HELPER_FREE;
}
helper_stateful_request *r = new helper_stateful_request;
- helper_stateful_server *srv;
r->callback = callback;
r->data = cbdataReference(data);
StatefulServerEnqueue(lastserver, r);
}
} else {
+ helper_stateful_server *srv;
if ((srv = StatefulGetFirstAvailable(hlp))) {
helperStatefulDispatch(srv, r);
} else
debugs(84, 9, "helperStatefulSubmit: placeholder: '" << r->placeholder << "', buf '" << buf << "'.");
}
+/*
+ * helperStatefulDefer
+ *
+ * find and add a deferred request to a helper
+ */
helper_stateful_server *
helperStatefulDefer(statefulhelper * hlp)
-/* find and add a deferred request to a server */
{
- if (hlp == NULL)
- {
+ if (hlp == NULL) {
debugs(84, 3, "helperStatefulDefer: hlp == NULL");
return NULL;
}
- dlink_node *n;
- helper_stateful_server *srv = NULL, *rv = NULL;
-
- debugs(84, 5, "helperStatefulDefer: Running servers " << hlp->n_running << ".");
+ debugs(84, 5, "helperStatefulDefer: Running servers " << hlp->n_running);
- if (hlp->n_running == 0)
- {
+ if (hlp->n_running == 0) {
debugs(84, 1, "helperStatefulDefer: No running servers!. ");
return NULL;
}
- rv = srv = StatefulGetFirstAvailable(hlp);
+ helper_stateful_server *rv = StatefulGetFirstAvailable(hlp);
- if (rv == NULL)
- {
+ if (rv == NULL) {
/*
* all currently busy; loop through servers and find server
* with the shortest queue
*/
- for (n = hlp->servers.head; n != NULL; n = n->next) {
- srv = (helper_stateful_server *)n->data;
+ for (dlink_node *n = hlp->servers.head; n != NULL; n = n->next) {
+ helper_stateful_server *srv = (helper_stateful_server *)n->data;
if (srv->flags.reserved == S_HELPER_RESERVED)
continue;
}
}
- if (rv == NULL)
- {
+ if (rv == NULL) {
debugs(84, 1, "helperStatefulDefer: None available.");
return NULL;
}
*/
{
statefulhelper *hlp = srv->parent;
- helper_stateful_request *r;
- r = srv->request;
+ helper_stateful_request *r = srv->request;
- if (r != NULL)
- {
+ if (r != NULL) {
/* reset attempt DURING an outstaning request */
debugs(84, 1, "helperStatefulReset: RESET During request " << hlp->id_name << " ");
srv->flags.busy = 0;
srv->flags.busy = 0;
- if (srv->queue.head)
- {
+ if (srv->queue.head) {
srv->flags.reserved = S_HELPER_DEFERRED;
helperStatefulServerKickQueue(srv);
- } else
- {
+ } else {
srv->flags.reserved = S_HELPER_FREE;
if ((srv->parent->OnEmptyQueue != NULL) && (srv->data))
}
}
+/*
+ * DPW 2007-05-08
+ *
+ * helperStatefulReleaseServer tells the helper that whoever was
+ * using it no longer needs its services.
+ *
+ * If the state is S_HELPER_DEFERRED, decrease the deferred count.
+ * If the count goes to zero, then it can become S_HELPER_FREE.
+ *
+ * If the state is S_HELPER_RESERVED, then it should always
+ * become S_HELPER_FREE.
+ */
void
helperStatefulReleaseServer(helper_stateful_server * srv)
-/*decrease the number of 'waiting' clients that set the helper to be DEFERRED */
{
+ debugs(84, 3, HERE << "srv-" << srv->index << " flags.reserved = " << srv->flags.reserved);
+ if (srv->flags.reserved = S_HELPER_FREE)
+ return;
+
srv->stats.releases++;
- if (srv->flags.reserved == S_HELPER_DEFERRED)
- {
+ if (srv->flags.reserved == S_HELPER_DEFERRED) {
assert(srv->deferred_requests);
srv->deferred_requests--;
+ if (srv->deferred_requests) {
+ debugs(0,0,HERE << "helperStatefulReleaseServer srv->deferred_requests=" << srv->deferred_requests);
+ return;
+ }
+ if (srv->queue.head) {
+ debugs(0,0,HERE << "helperStatefulReleaseServer srv->queue.head not NULL");
+ return;
+ }
}
- if (!(srv->deferred_requests) && (srv->flags.reserved == S_HELPER_DEFERRED) && !(srv->queue.head))
- {
- srv->flags.reserved = S_HELPER_FREE;
-
- if ((srv->parent->OnEmptyQueue != NULL) && (srv->data))
- srv->parent->OnEmptyQueue(srv->data);
- }
+ srv->flags.reserved = S_HELPER_FREE;
+ if (srv->parent->OnEmptyQueue != NULL && srv->data)
+ srv->parent->OnEmptyQueue(srv->data);
}
void *
if (!helperStartStats(sentry, hlp, label))
return;
- dlink_node *link;
storeAppendPrintf(sentry, "program: %s\n",
hlp->cmdline->key);
storeAppendPrintf(sentry, "number running: %d of %d\n",
"Offset",
"Request");
- for (link = hlp->servers.head; link; link = link->next) {
+ for (dlink_node *link = hlp->servers.head; link; link = link->next) {
helper_server *srv = (helper_server*)link->data;
double tt = 0.001 * (srv->requests[0] ? tvSubMsec(srv->requests[0]->dispatch_time, current_time) : tvSubMsec(srv->dispatch_time, srv->answer_time));
storeAppendPrintf(sentry, "%7d\t%7d\t%7d\t%11d\t%c%c%c%c\t%7.3f\t%7d\t%s\n",
if (!helperStartStats(sentry, hlp, label))
return;
- helper_stateful_server *srv;
- dlink_node *link;
- double tt;
storeAppendPrintf(sentry, "program: %s\n",
hlp->cmdline->key);
storeAppendPrintf(sentry, "number running: %d of %d\n",
"Offset",
"Request");
- for (link = hlp->servers.head; link; link = link->next) {
- srv = (helper_stateful_server *)link->data;
- tt = 0.001 * tvSubMsec(srv->dispatch_time,
+ for (dlink_node *link = hlp->servers.head; link; link = link->next) {
+ helper_stateful_server *srv = (helper_stateful_server *)link->data;
+ double tt = 0.001 * tvSubMsec(srv->dispatch_time,
srv->flags.busy ? current_time : srv->answer_time);
storeAppendPrintf(sentry, "%7d\t%7d\t%7d\t%11d\t%20d\t%c%c%c%c%c\t%7.3f\t%7d\t%s\n",
srv->index + 1,
(int) srv->deferred_requests,
srv->flags.busy ? 'B' : ' ',
srv->flags.closing ? 'C' : ' ',
- srv->flags.reserved != S_HELPER_FREE ? 'R' : ' ',
+ srv->flags.reserved == S_HELPER_RESERVED ? 'R' : (srv->flags.reserved == S_HELPER_DEFERRED ? 'D' : ' '),
srv->flags.shutdown ? 'S' : ' ',
srv->request ? (srv->request->placeholder ? 'P' : ' ') : ' ',
tt < 0.0 ? 0.0 : tt,
return;
}
- debugs(84, 5, "helperHandleRead: " << len << " bytes from " << hlp->id_name << " #" << srv->index + 1 << ".");
+ debugs(84, 5, "helperHandleRead: " << len << " bytes from " << hlp->id_name << " #" << srv->index + 1);
if (flag != COMM_OK || len <= 0) {
if (len < 0)
}
debugs(84, 5, "helperStatefulHandleRead: " << len << " bytes from " <<
- hlp->id_name << " #" << srv->index + 1 << ".");
+ hlp->id_name << " #" << srv->index + 1);
if (flag != COMM_OK || len <= 0) {
{
dlink_node *n;
helper_stateful_server *srv = NULL;
- debugs(84, 5, "StatefulGetFirstAvailable: Running servers " << hlp->n_running << ".");
+ debugs(84, 5, "StatefulGetFirstAvailable: Running servers " << hlp->n_running);
if (hlp->n_running == 0)
return NULL;
if ((hlp->IsAvailable != NULL) && (srv->data != NULL) && !(hlp->IsAvailable(srv->data)))
continue;
+ debugs(84, 5, "StatefulGetFirstAvailable: returning srv-" << srv->index);
return srv;
}