Windows: cm_QueueBKGRequest improvements
[openafs.git] / src / WINNT / afsd / cm_daemon.c
index 06e9a18..f8b9f77 100644 (file)
@@ -41,6 +41,8 @@ long cm_daemonCheckOfflineVolInterval = 600;
 long cm_daemonPerformanceTuningInterval = 0;
 long cm_daemonRankServerInterval = 600;
 long cm_daemonRDRShakeExtentsInterval = 0;
+long cm_daemonAfsdHookReloadInterval = 0;
+long cm_daemonEAccesCheckInterval = 1800;
 
 osi_rwlock_t *cm_daemonLockp;
 afs_uint64 *cm_bkgQueueCountp;         /* # of queued requests */
@@ -263,8 +265,9 @@ void * cm_BkgDaemon(void * vparm)
 void cm_QueueBKGRequest(cm_scache_t *scp, cm_bkgProc_t *procp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_uint32 p4,
        cm_user_t *userp, cm_req_t *reqp)
 {
-    cm_bkgRequest_t *rp;
-    afs_uint32 daemonID = scp->fid.hash % cm_nDaemons;
+    cm_bkgRequest_t *rp, *rpq;
+    afs_uint32 daemonID;
+    int duplicate = 0;
 
     rp = malloc(sizeof(*rp));
     memset(rp, 0, sizeof(*rp));
@@ -280,12 +283,40 @@ void cm_QueueBKGRequest(cm_scache_t *scp, cm_bkgProc_t *procp, afs_uint32 p1, af
     rp->p4 = p4;
     rp->req = *reqp;
 
+    /* Use separate queues for fetch and store operations */
+    daemonID = scp->fid.hash % (cm_nDaemons/2) * 2;
+    if (procp == cm_BkgStore)
+        daemonID++;
+
     lock_ObtainWrite(&cm_daemonLockp[daemonID]);
-    cm_bkgQueueCountp[daemonID]++;
-    osi_QAddH((osi_queue_t **) &cm_bkgListpp[daemonID], (osi_queue_t **)&cm_bkgListEndpp[daemonID], &rp->q);
+    /* Check to see if this is a duplicate request */
+    for (rpq = cm_bkgListpp[daemonID]; rpq; rpq = (cm_bkgRequest_t *) osi_QNext(&rpq->q))
+    {
+        if ( rpq->p1 == p1 &&
+             rpq->p3 == p3 &&
+             rpq->procp == procp &&
+             rpq->p2 == p2 &&
+             rpq->p4 == p4 &&
+             rpq->scp == scp &&
+             rpq->userp == userp)
+        {
+            /* found a duplicate; update request with latest info */
+            duplicate = 1;
+            break;
+        }
+    }
+
+    if (!duplicate) {
+        cm_bkgQueueCountp[daemonID]++;
+        osi_QAddH((osi_queue_t **) &cm_bkgListpp[daemonID], (osi_queue_t **)&cm_bkgListEndpp[daemonID], &rp->q);
+    }
     lock_ReleaseWrite(&cm_daemonLockp[daemonID]);
 
-    osi_Wakeup((LONG_PTR) &cm_bkgListpp[daemonID]);
+    if (duplicate) {
+        free(rp);
+    } else {
+        osi_Wakeup((LONG_PTR) &cm_bkgListpp[daemonID]);
+    }
 }
 
 static int
@@ -438,6 +469,13 @@ cm_DaemonCheckInit(void)
        cm_daemonRankServerInterval = dummy;
     afsi_log("daemonRankServerInterval is %d", cm_daemonRankServerInterval);
 
+    dummyLen = sizeof(DWORD);
+    code = RegQueryValueEx(parmKey, "daemonAfsdHookReloadInterval", NULL, NULL,
+                           (BYTE *) &dummy, &dummyLen);
+    if (code == ERROR_SUCCESS && dummy)
+       cm_daemonAfsdHookReloadInterval = dummy;
+    afsi_log("daemonAfsdHookReloadInterval is %d", cm_daemonAfsdHookReloadInterval);
+
     RegCloseKey(parmKey);
 
     if (cm_daemonPerformanceTuningInterval)
@@ -496,10 +534,13 @@ void * cm_Daemon(void *vparm)
     time_t lastPerformanceCheck;
     time_t lastServerRankCheck;
     time_t lastRDRShakeExtents;
+    time_t lastAfsdHookReload;
+    time_t lastEAccesCheck;
     char thostName[200];
     unsigned long code;
     struct hostent *thp;
-    HMODULE hHookDll;
+    HMODULE hHookDll = NULL;
+    AfsdDaemonHook daemonHook = NULL;
     char * name = "cm_Daemon_ShutdownEvent";
     int configureFirewall = IsWindowsFirewallPresent();
     int bAddrChangeCheck = 0;
@@ -552,6 +593,13 @@ void * cm_Daemon(void *vparm)
     lastServerRankCheck = now - cm_daemonRankServerInterval/2 * (rand() % cm_daemonRankServerInterval);
     if (cm_daemonRDRShakeExtentsInterval)
         lastRDRShakeExtents = now - cm_daemonRDRShakeExtentsInterval/2 * (rand() % cm_daemonRDRShakeExtentsInterval);
+    if (cm_daemonAfsdHookReloadInterval)
+        lastAfsdHookReload = now;
+    lastEAccesCheck = now;
+
+    hHookDll = cm_LoadAfsdHookLib();
+    if (hHookDll)
+        daemonHook = ( AfsdDaemonHook ) GetProcAddress(hHookDll, AFSD_DAEMON_HOOK);
 
     while (daemon_ShutdownFlag == 0) {
         if (powerStateSuspended) {
@@ -704,6 +752,16 @@ void * cm_Daemon(void *vparm)
            now = osi_Time();
         }
 
+        if (now > lastEAccesCheck + cm_daemonEAccesCheckInterval &&
+             daemon_ShutdownFlag == 0 &&
+             powerStateSuspended == 0) {
+            lastEAccesCheck = now;
+            cm_EAccesClearOutdatedEntries();
+            if (daemon_ShutdownFlag == 1)
+                break;
+           now = osi_Time();
+        }
+
         if (cm_daemonRDRShakeExtentsInterval &&
             now > lastRDRShakeExtents + cm_daemonRDRShakeExtentsInterval &&
             daemon_ShutdownFlag == 0 &&
@@ -719,17 +777,22 @@ void * cm_Daemon(void *vparm)
         }
 
         /* allow an exit to be called prior to stopping the service */
-        hHookDll = cm_LoadAfsdHookLib();
-        if (hHookDll)
-        {
-            BOOL hookRc = TRUE;
-            AfsdDaemonHook daemonHook = ( AfsdDaemonHook ) GetProcAddress(hHookDll, AFSD_DAEMON_HOOK);
-            if (daemonHook)
-            {
-                hookRc = daemonHook();
+        if (cm_daemonAfsdHookReloadInterval &&
+            lastAfsdHookReload != 0 && lastAfsdHookReload < now) {
+            if (hHookDll) {
+                FreeLibrary(hHookDll);
+                hHookDll = NULL;
+                daemonHook = NULL;
             }
-            FreeLibrary(hHookDll);
-            hHookDll = NULL;
+
+            hHookDll = cm_LoadAfsdHookLib();
+            if (hHookDll)
+                daemonHook = ( AfsdDaemonHook ) GetProcAddress(hHookDll, AFSD_DAEMON_HOOK);
+        }
+
+        if (daemonHook)
+        {
+            BOOL hookRc = daemonHook();
 
             if (hookRc == FALSE)
             {
@@ -761,6 +824,10 @@ void * cm_Daemon(void *vparm)
         thrd_Sleep(500);
     }
 
+    if (hHookDll) {
+        FreeLibrary(hHookDll);
+    }
+
     thrd_SetEvent(cm_Daemon_ShutdownEvent);
     pthread_exit(NULL);
     return NULL;