Update NEWS for 1.6.22
[pkg-k5-afs_openafs.git] / src / WINNT / afsadmsvr / TaAfsAdmSvrCallback.cpp
blob9dca4165677fb214595b2ea81bef4b274c92c92b
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
10 #include <winsock2.h>
11 #include <ws2tcpip.h>
13 #include <afs/param.h>
14 #include <afs/stds.h>
16 #include "TaAfsAdmSvrInternal.h"
19 * VARIABLES __________________________________________________________________
23 typedef struct
25 CALLBACKTYPE Type;
26 BOOL fFinished;
27 LPASACTION pAction;
28 } CALLBACKDATA, *LPCALLBACKDATA;
30 static struct
32 HANDLE heCallback;
33 LPHASHLIST pListCallbacks;
34 BOOL fStopManagers;
35 size_t cManagers;
36 } l;
40 * CALLBACKS __________________________________________________________________
44 void AfsAdmSvr_FreeCallbackData (LPCALLBACKDATA pData)
46 if (pData)
48 if (pData->pAction)
49 Delete (pData->pAction);
50 Delete (pData);
55 void AfsAdmSvr_CallbackManager (void)
57 AfsAdmSvr_Enter();
58 if ((++l.cManagers) == 1)
60 l.heCallback = CreateEvent (NULL, TRUE, FALSE, TEXT("AfsAdmSvr_CallbackManager Event"));
61 l.pListCallbacks = New (HASHLIST);
63 AfsAdmSvr_Leave();
65 for (;;)
67 WaitForSingleObjectEx (l.heCallback, INFINITE, FALSE);
69 if (l.fStopManagers)
70 break;
72 // We must ensure that we don't block the server's operations because
73 // a callback doesn't go through; since other operations may need
74 // access to the l.pListCallbacks structure in order to queue new
75 // callbacks, we can't leave it locked by issuing callbacks while
76 // enumerating it. Instead we'll copy the list into a local copy,
77 // clear it, and enumerate that local copy--other threads can then
78 // continue to add new requests to l.pListCallbacks.
80 AfsAdmSvr_Enter();
82 LPHASHLIST pList = New (HASHLIST);
83 LPENUM pEnum;
84 for (pEnum = l.pListCallbacks->FindFirst(); pEnum; pEnum = pEnum->FindNext())
86 LPCALLBACKDATA pData = (LPCALLBACKDATA)( pEnum->GetObject() );
87 pList->Add (pData);
88 l.pListCallbacks->Remove (pData);
91 ResetEvent (l.heCallback);
92 AfsAdmSvr_Leave();
94 // Now enumerate that copied list, and issue callbacks for each item.
96 for (pEnum = pList->FindFirst(); pEnum; pEnum = pEnum->FindNext())
98 LPCALLBACKDATA pData = (LPCALLBACKDATA)( pEnum->GetObject() );
100 try {
101 switch (pData->Type)
103 case cbtACTION:
104 AfsAdmSvrCallback_Action (pData->pAction, pData->fFinished);
105 break;
107 } catch(...) {
111 pList->Remove (pData);
112 AfsAdmSvr_FreeCallbackData (pData);
115 Delete (pList);
118 AfsAdmSvr_Enter();
119 if ((--l.cManagers) == 0)
121 Delete (l.pListCallbacks);
122 l.pListCallbacks = NULL;
123 CloseHandle (l.heCallback);
124 l.heCallback = NULL;
126 AfsAdmSvr_Leave();
130 void AfsAdmSvr_PostCallback (CALLBACKTYPE Type, BOOL fFinished, LPASACTION pAction, DWORD dwRemoveMe)
132 AfsAdmSvr_Enter();
133 if (l.pListCallbacks)
135 LPCALLBACKDATA pData = New (CALLBACKDATA);
136 memset (pData, 0x00, sizeof(CALLBACKDATA));
137 pData->Type = Type;
138 pData->fFinished = fFinished;
139 if (pAction)
141 pData->pAction = New (ASACTION);
142 memcpy (pData->pAction, pAction, sizeof(ASACTION));
145 l.pListCallbacks->Add (pData);
146 SetEvent (l.heCallback);
148 AfsAdmSvr_Leave();
152 void AfsAdmSvr_PostCallback (CALLBACKTYPE Type, BOOL fFinished, LPASACTION pAction)
154 AfsAdmSvr_PostCallback (Type, fFinished, pAction, 0);
158 void AfsAdmSvr_StopCallbackManagers (void)
160 AfsAdmSvr_Enter();
161 if (l.cManagers)
163 l.fStopManagers = TRUE;
164 SetEvent (l.heCallback);
166 AfsAdmSvr_Leave();