Cleaned up some mutex names.
/*
* The contents of this file are subject to the AOLserver Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://aolserver.lcs.mit.edu/.
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is AOLserver Code and related documentation
* distributed by AOL.
*
* The Initial Developer of the Original Code is America Online,
* Inc. Portions created by AOL are Copyright (C) 1999 America Online,
* Inc. All Rights Reserved.
*
* Alternatively, the contents of this file may be used under the terms
* of the GNU General Public License (the "GPL"), in which case the
* provisions of GPL are applicable instead of those above. If you wish
* to allow use of your version of this file only under the terms of the
* GPL and not to allow others to use your version of this file under the
* License, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the GPL.
* If you do not delete the provisions above, a recipient may use your
* version of this file under either the License or the GPL.
*/
/*
* callbacks.c --
*
* Support for Callbacks
*
* These functions allow the registration of callbacks
* that are run at various points during the server's execution.
*/
static const char *RCSID = "@(#) $Header: /cvsroot/aolserver/aolserver/nsd/callbacks.c,v 1.6 2002/05/15 20:07:47 jgdavidson Exp $, compiled: " __DATE__ " " __TIME__;
#include "nsd.h"
/*
* This structure is used as nodes in a linked list of callbacks.
*/
typedef struct Callback {
struct Callback *nextPtr;
Ns_Callback *proc;
void *arg;
} Callback;
/*
* Local functions defined in this file
*/
static Ns_ThreadProc RunThread;
static void RunCallbacks(Callback *firstPtr);
static void RunStart(Callback **firstPtrPtr, Ns_Thread *threadPtr);
static void RunWait(Callback **firstPtrPtr, Ns_Thread *threadPtr, Ns_Time *toPtr);
static void *RegisterAt(Callback **firstPtrPtr, Ns_Callback *proc, void *arg);
/*
* Static variables defined in this file
*/
static Callback *firstPreStartup;
static Callback *firstStartup;
static Callback *firstSignal;
static Callback *firstServerShutdown;
static Callback *firstShutdown;
static Callback *firstExit;
static Callback *firstReady;
static Ns_Mutex lock;
static Ns_Cond cond;
static int shutdownPending;
static Ns_Thread serverShutdownThread;
void *
Ns_RegisterAtReady(Ns_Callback *proc, void *arg)
{
return RegisterAt(&firstReady, proc, arg);
}
void
NsRunAtReadyProcs(void)
{
RunCallbacks(firstReady);
}
/*
*----------------------------------------------------------------------
*
* Ns_RegisterAtStartup --
*
* Register a callback to run at server startup
*
* Results:
* None
*
* Side effects:
* The callback will be registered
*
*----------------------------------------------------------------------
*/
void *
Ns_RegisterAtStartup(Ns_Callback *proc, void *arg)
{
return RegisterAt(&firstStartup, proc, arg);
}
/*
*----------------------------------------------------------------------
*
* Ns_RegisterAtPreStartup --
*
* Register a callback to run at pre-server startup
*
* Results:
* None
*
* Side effects:
* The callback will be registered
*
*----------------------------------------------------------------------
*/
void *
Ns_RegisterAtPreStartup(Ns_Callback *proc, void *arg)
{
return RegisterAt(&firstPreStartup, proc, arg);
}
/*
*----------------------------------------------------------------------
*
* Ns_RegisterAtSignal --
*
* Register a callback to run when a signal arrives
*
* Results:
* None
*
* Side effects:
* The callback will be registered
*
*----------------------------------------------------------------------
*/
void *
Ns_RegisterAtSignal(Ns_Callback * proc, void *arg)
{
return RegisterAt(&firstSignal, proc, arg);
}
/*
*----------------------------------------------------------------------
*
* Ns_RegisterAtServerShutdown --
*
* Register a callback to run at server shutdown. This is
* identical to Ns_RegisterShutdown and only exists for
* historical reasons.
*
* Results:
* None.
*
* Side effects:
* The callback will be registered
*
*----------------------------------------------------------------------
*/
void *
Ns_RegisterAtServerShutdown(Ns_Callback *proc, void *arg)
{
return RegisterAt(&firstServerShutdown, proc, arg);
}
void *
Ns_RegisterServerShutdown(char *ignored, Ns_Callback *proc, void *arg)
{
return Ns_RegisterAtServerShutdown(proc, arg);
}
/*
*----------------------------------------------------------------------
*
* Ns_RegisterAtShutdown --
*
* Register a callback to run at server shutdown.
*
* Results:
* None.
*
* Side effects:
* The callback will be registered.
*
*----------------------------------------------------------------------
*/
void *
Ns_RegisterAtShutdown(Ns_Callback *proc, void *arg)
{
return RegisterAt(&firstShutdown, proc, arg);
}
void *
Ns_RegisterShutdown(Ns_Callback *proc, void *arg)
{
return Ns_RegisterAtShutdown(proc, arg);
}
/*
*----------------------------------------------------------------------
*
* Ns_RegisterAtExit --
*
* Register a callback to be run at server exit.
*
* Results:
* None.
*
* Side effects:
* The callback will be registerd.
*
*----------------------------------------------------------------------
*/
void *
Ns_RegisterAtExit(Ns_Callback * proc, void *arg)
{
return RegisterAt(&firstExit, proc, arg);
}
/*
*----------------------------------------------------------------------
*
* NsRunStartupProcs --
*
* Run any callbacks registered for server startup.
*
* Results:
* None.
*
* Side effects:
* Callbacks called back.
*
*----------------------------------------------------------------------
*/
void
NsRunStartupProcs(void)
{
RunCallbacks(firstStartup);
}
/*
*----------------------------------------------------------------------
*
* NsRunPreStartupProcs --
*
* Run any callbacks registered for pre-server startup.
*
* Results:
* None.
*
* Side effects:
* Callbacks called back.
*
*----------------------------------------------------------------------
*/
void
NsRunPreStartupProcs(void)
{
RunCallbacks(firstPreStartup);
}
/*
*----------------------------------------------------------------------
*
* NsRunSignalProcs --
*
* Run any callbacks registered for when a signal arrives
*
* Results:
* None.
*
* Side effects:
* Callbacks called back.
*
*----------------------------------------------------------------------
*/
void
NsRunSignalProcs(void)
{
RunCallbacks(firstSignal);
}
/*
*----------------------------------------------------------------------
*
* NsRunExitProcs --
*
* Run any callbacks registered for server startup, then
* shutdown, then exit.
*
* Results:
* None.
*
* Side effects:
* Callbacks called back.
*
*----------------------------------------------------------------------
*/
void
NsStartShutdownProcs(void)
{
Ns_MutexLock(&lock);
shutdownPending = 1;
Ns_MutexUnlock(&lock);
RunStart(&firstServerShutdown, &serverShutdownThread);
}
void
NsWaitShutdownProcs(Ns_Time *toPtr)
{
Ns_Thread thread;
RunWait(&firstServerShutdown, &serverShutdownThread, toPtr);
RunStart(&firstShutdown, &thread);
RunWait(&firstShutdown, &thread, toPtr);
}
void
NsRunAtExitProcs(void)
{
RunCallbacks(firstExit);
}
/*
*----------------------------------------------------------------------
*
* RegisterAt --
*
* A generic function that registers callbacks for any event
*
* Results:
* A pointer to the newly-allocated Callback structure
*
* Side effects:
* A Callback struct will be alloacated and put in the linked list.
*
*----------------------------------------------------------------------
*/
static void *
RegisterAt(Callback **firstPtrPtr, Ns_Callback *proc, void *arg)
{
Callback *cbPtr;
static int first = 1;
cbPtr = ns_malloc(sizeof(Callback));
cbPtr->proc = proc;
cbPtr->arg = arg;
Ns_MutexLock(&lock);
if (first) {
Ns_MutexSetName(&lock, "ns:callbacks");
first = 0;
}
if (shutdownPending) {
ns_free(cbPtr);
cbPtr = NULL;
} else {
cbPtr->nextPtr = *firstPtrPtr;
*firstPtrPtr = cbPtr;
}
Ns_MutexUnlock(&lock);
return (void *) cbPtr;
}
/*
*----------------------------------------------------------------------
*
* RunCallbacks --
*
* Run all callbacks in the passed-in linked list
*
* Results:
* None
*
* Side effects:
* Callbacks called back.
*
*----------------------------------------------------------------------
*/
static void
RunCallbacks(Callback *cbPtr)
{
while (cbPtr != NULL) {
(*cbPtr->proc) (cbPtr->arg);
cbPtr = cbPtr->nextPtr;
}
}
static void
RunStart(Callback **firstPtrPtr, Ns_Thread *threadPtr)
{
Ns_MutexLock(&lock);
if (*firstPtrPtr != NULL) {
Ns_ThreadCreate(RunThread, firstPtrPtr, 0, threadPtr);
} else {
*threadPtr = NULL;
}
Ns_MutexUnlock(&lock);
}
static void
RunWait(Callback **firstPtrPtr, Ns_Thread *threadPtr, Ns_Time *toPtr)
{
int status;
status = NS_OK;
Ns_MutexLock(&lock);
while (status == NS_OK && *firstPtrPtr != NULL) {
status = Ns_CondTimedWait(&cond, &lock, toPtr);
}
Ns_MutexUnlock(&lock);
if (status != NS_OK) {
Ns_Log(Warning, "callbacks: timeout waiting for shutdown procs");
} else if (*threadPtr != NULL) {
Ns_ThreadJoin(threadPtr, NULL);
}
}
static void
RunThread(void *arg)
{
Callback **firstPtrPtr = arg;
Callback *firstPtr;
Ns_ThreadSetName("-shutdown-");
Ns_MutexLock(&lock);
firstPtr = *firstPtrPtr;
Ns_MutexUnlock(&lock);
RunCallbacks(firstPtr);
Ns_MutexLock(&lock);
while (*firstPtrPtr != NULL) {
firstPtr = *firstPtrPtr;
*firstPtrPtr = firstPtr->nextPtr;
ns_free(firstPtr);
}
Ns_CondSignal(&cond);
Ns_MutexUnlock(&lock);
}
static void
AppendList(Tcl_DString *dsPtr, char *list, Callback *firstPtr)
{
Callback *cbPtr;
cbPtr = firstPtr;
while (cbPtr != NULL) {
Tcl_DStringStartSublist(dsPtr);
Tcl_DStringAppendElement(dsPtr, list);
Ns_GetProcInfo(dsPtr, (void *) cbPtr->proc, cbPtr->arg);
Tcl_DStringEndSublist(dsPtr);
cbPtr = cbPtr->nextPtr;
}
}
void
NsGetCallbacks(Tcl_DString *dsPtr)
{
Ns_MutexLock(&lock);
AppendList(dsPtr, "prestartup", firstPreStartup);
AppendList(dsPtr, "startup", firstStartup);
AppendList(dsPtr, "signal", firstSignal);
AppendList(dsPtr, "servershutdown", firstServerShutdown);
AppendList(dsPtr, "shutdown", firstShutdown);
AppendList(dsPtr, "exit", firstExit);
Ns_MutexUnlock(&lock);
}
|
Back to SourceForge.net Powered by ViewCVS 1.0-dev |