Standardize License information
[openafs.git] / src / WINNT / afsadmsvr / TaAfsAdmSvrClientCache.cpp
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
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  */
9
10 extern "C" {
11 #include <afs/param.h>
12 #include <afs/stds.h>
13 }
14
15 #include "TaAfsAdmSvrClientInternal.h"
16 #include <WINNT/AfsAppLib.h>
17
18
19 /*
20  * VARIABLES __________________________________________________________________
21  *
22  */
23
24 typedef struct
25    {
26    ASID idCell;
27    LPHASHLIST pCache;
28    LPHASHLISTKEY pCacheKeyAsid;
29    DWORD cReqCache;
30    } CELLCACHE, *LPCELLCACHE;
31
32 static struct
33    {
34    LPHASHLIST pCells;
35    LPHASHLISTKEY pCellsKeyAsid;
36    } l;
37
38
39 /*
40  * PROTOTYPES _________________________________________________________________
41  *
42  */
43
44 BOOL CALLBACK CacheKeyAsid_Compare (LPHASHLISTKEY pKey, PVOID pObject, PVOID pData);
45 HASHVALUE CALLBACK CacheKeyAsid_HashObject (LPHASHLISTKEY pKey, PVOID pObject);
46 HASHVALUE CALLBACK CacheKeyAsid_HashData (LPHASHLISTKEY pKey, PVOID pData);
47
48 BOOL CALLBACK CellsKeyAsid_Compare (LPHASHLISTKEY pKey, PVOID pObject, PVOID pData);
49 HASHVALUE CALLBACK CellsKeyAsid_HashObject (LPHASHLISTKEY pKey, PVOID pObject);
50 HASHVALUE CALLBACK CellsKeyAsid_HashData (LPHASHLISTKEY pKey, PVOID pData);
51
52
53 /*
54  * ROUTINES ___________________________________________________________________
55  *
56  */
57
58 LPCELLCACHE GetCellCache (ASID idCell)
59 {
60    if (!l.pCells)
61       return NULL;
62
63    return (LPCELLCACHE)(l.pCellsKeyAsid->GetFirstObject (&idCell));
64 }
65
66
67 BOOL CreateCellCache (ASID idCell)
68 {
69    asc_Enter();
70
71    if (!l.pCells)
72       {
73       l.pCells = New (HASHLIST);
74       l.pCells->SetCriticalSection (asc_GetCriticalSection());
75       l.pCellsKeyAsid = l.pCells->CreateKey (TEXT("ASID"), CellsKeyAsid_Compare, CellsKeyAsid_HashObject, CellsKeyAsid_HashData);
76       }
77
78    LPCELLCACHE pcc;
79    if ((pcc = GetCellCache (idCell)) == NULL)
80       {
81       pcc = New (CELLCACHE);
82       memset (pcc, 0x00, sizeof(CELLCACHE));
83       pcc->idCell = idCell;
84       pcc->pCache = New (HASHLIST);
85       pcc->pCache->SetCriticalSection (asc_GetCriticalSection());
86       pcc->pCacheKeyAsid = pcc->pCache->CreateKey (TEXT("ASID"), CacheKeyAsid_Compare, CacheKeyAsid_HashObject, CacheKeyAsid_HashData);
87       l.pCells->Add (pcc);
88       }
89    pcc->cReqCache ++;
90
91    asc_Leave();
92    return TRUE;
93 }
94
95
96 BOOL DestroyCellCache (ASID idCell)
97 {
98    asc_Enter();
99
100    LPCELLCACHE pcc;
101    if ((pcc = GetCellCache (idCell)) == NULL)
102       {
103       asc_Leave();
104       return FALSE;
105       }
106
107    if (!pcc->cReqCache || !(--(pcc->cReqCache)))
108       {
109       if (pcc->pCache)
110          {
111          for (LPENUM pEnum = pcc->pCache->FindFirst(); pEnum; pEnum = pEnum->FindNext())
112             {
113             LPASOBJPROP pProp = (LPASOBJPROP)( pEnum->GetObject() );
114             pcc->pCache->Remove (pProp);
115             Delete (pProp);
116             }
117
118          Delete (pcc->pCache);
119          }
120
121       l.pCells->Remove (pcc);
122       Delete (pcc);
123       }
124
125    asc_Leave();
126    return TRUE;
127 }
128
129
130 LPASOBJPROP GetCachedProperties (ASID idCell, ASID idObject)
131 {
132    LPASOBJPROP pCachedProperties = NULL;
133    asc_Enter();
134
135    LPCELLCACHE pcc;
136    if ((pcc = GetCellCache (idCell)) != NULL)
137       {
138       pCachedProperties = (LPASOBJPROP)(pcc->pCacheKeyAsid->GetFirstObject (&idObject));
139       }
140
141    asc_Leave();
142    return pCachedProperties;
143 }
144
145
146 void UpdateCachedProperties (ASID idCell, ASID idObject, LPASOBJPROP pProperties)
147 {
148    if (pProperties)
149       {
150       asc_Enter();
151
152       LPCELLCACHE pcc;
153       if ((pcc = GetCellCache (idCell)) != NULL)
154          {
155          LPASOBJPROP pCachedProperties;
156          if ((pCachedProperties = (LPASOBJPROP)(pcc->pCacheKeyAsid->GetFirstObject (&idObject))) == NULL)
157             {
158             pCachedProperties = New (ASOBJPROP);
159             memcpy (pCachedProperties, pProperties, sizeof(ASOBJPROP));
160             pcc->pCache->Add (pCachedProperties);
161             }
162          else // Just update?
163             {
164             memcpy (pCachedProperties, pProperties, sizeof(ASOBJPROP));
165             // Note: don't need to call pcc->pCache->Update(), because
166             // we haven't affected any indices (the old and new ASOBJPROP
167             // structures should have the same ASID)
168             }
169          }
170
171       NotifyObjectListeners (idCell, idObject);
172       asc_Leave();
173       }
174 }
175
176
177 BOOL RefreshCachedProperties (DWORD idClient, ASID idCell, ASID idObject, AFSADMSVR_GET_LEVEL GetLevel, ULONG *pStatus)
178 {
179    BOOL rc = TRUE;
180    ULONG status = 0;
181
182    RpcTryExcept
183       {
184       LPASOBJPROP pProperties = GetCachedProperties (idCell, idObject);
185       DWORD verProperties = (pProperties) ? (pProperties->verProperties) : verPROP_NO_OBJECT;
186
187       ASOBJPROP NewProperties;
188       if ((rc = AfsAdmSvr_GetObject (idClient, RETURN_IF_OUT_OF_DATE, GetLevel, idObject, verProperties, &NewProperties, &status)) != FALSE)
189          {
190          if (NewProperties.idObject == idObject)
191             {
192             UpdateCachedProperties (idCell, idObject, &NewProperties);
193             }
194          }
195       }
196    RpcExcept(1)
197       {
198       rc = FALSE;
199       status = RPC_S_CALL_FAILED_DNE;
200       }
201    RpcEndExcept
202
203    if (!rc && pStatus)
204       *pStatus = status;
205    return rc;
206 }
207
208
209 BOOL RefreshCachedProperties (DWORD idClient, ASID idCell, LPASIDLIST pAsidList, AFSADMSVR_GET_LEVEL GetLevel, ULONG *pStatus)
210 {
211    BOOL rc = TRUE;
212    ULONG status = 0;
213
214    if (pAsidList->cEntries)
215       {
216       RpcTryExcept
217          {
218          for (size_t iObject = 0; iObject < pAsidList->cEntries; ++iObject)
219             {
220             LPASOBJPROP pProperties = GetCachedProperties (idCell, pAsidList->aEntries[ iObject ].idObject);
221             pAsidList->aEntries[ iObject ].lParam = (pProperties) ? (pProperties->verProperties) : verPROP_NO_OBJECT;
222             }
223
224          LPASOBJPROPLIST pNewProperties = NULL;
225          if ((rc = AfsAdmSvr_GetObjects (idClient, RETURN_IF_OUT_OF_DATE, GetLevel, pAsidList, &pNewProperties, &status)) != FALSE)
226             {
227             if (pNewProperties)
228                {
229                for (size_t iObject = 0; iObject < pNewProperties->cEntries; ++iObject)
230                   {
231                   UpdateCachedProperties (idCell, pNewProperties->aEntries[ iObject ].ObjectProperties.idObject, &pNewProperties->aEntries[ iObject ].ObjectProperties);
232                   }
233                AfsAdmSvr_FreeObjPropList (&pNewProperties);
234                }
235             }
236          }
237       RpcExcept(1)
238          {
239          rc = FALSE;
240          status = RPC_S_CALL_FAILED_DNE;
241          }
242       RpcEndExcept
243       }
244
245    if (!rc && pStatus)
246       *pStatus = status;
247    return rc;
248 }
249
250
251 /*
252  * HASHLIST KEYS ______________________________________________________________
253  *
254  */
255
256 BOOL CALLBACK CacheKeyAsid_Compare (LPHASHLISTKEY pKey, PVOID pObject, PVOID pData)
257 {
258    return (((LPASOBJPROP)pObject)->idObject == *(ASID*)pData);
259 }
260
261 HASHVALUE CALLBACK CacheKeyAsid_HashObject (LPHASHLISTKEY pKey, PVOID pObject)
262 {
263    return CacheKeyAsid_HashData (pKey, &((LPASOBJPROP)pObject)->idObject);
264 }
265
266 HASHVALUE CALLBACK CacheKeyAsid_HashData (LPHASHLISTKEY pKey, PVOID pData)
267 {
268    return (HASHVALUE)*(ASID*)pData;
269 }
270
271
272 BOOL CALLBACK CellsKeyAsid_Compare (LPHASHLISTKEY pKey, PVOID pObject, PVOID pData)
273 {
274    return (((LPCELLCACHE)pObject)->idCell == *(ASID*)pData);
275 }
276
277 HASHVALUE CALLBACK CellsKeyAsid_HashObject (LPHASHLISTKEY pKey, PVOID pObject)
278 {
279    return CellsKeyAsid_HashData (pKey, &((LPCELLCACHE)pObject)->idCell);
280 }
281
282 HASHVALUE CALLBACK CellsKeyAsid_HashData (LPHASHLISTKEY pKey, PVOID pData)
283 {
284    return (HASHVALUE)*(ASID*)pData;
285 }
286