]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Hgfs Server: Move async request globals into the Hgfs session
authorOliver Kurth <okurth@vmware.com>
Fri, 15 Sep 2017 18:23:49 +0000 (11:23 -0700)
committerOliver Kurth <okurth@vmware.com>
Fri, 15 Sep 2017 18:23:49 +0000 (11:23 -0700)
This change moves the async request globals into the Hgfs session.
They are only applicable to a session and only used during a session's
lifetime, so making them global is not necessary and means that
they take up resources when not used.

Details:
- Move the previous globals into a structure for async requests.
- Add the async requests structure to the HgfsSessionInfo object.
- Create a set of helper functions to init, exit and manipulate the
  async requests structure.
- Remove the calls to init and teardown the globals now they don't
  exist.
- Add the helper calls to the session creation and destruction.
- Add the helper calls to replace adding a new async request, removing
  an async request, and waiting for all async requests to complete.

open-vm-tools/lib/hgfsServer/hgfsServer.c
open-vm-tools/lib/hgfsServer/hgfsServerInt.h

index 3d5ae7c5d08a07f5c7275ae59271dd9367e783c8..fb911da3fbe8b17e61180dec92322c3924f55182 100644 (file)
@@ -189,13 +189,6 @@ static HgfsServerConfig gHgfsCfgSettings = {
  */
 static Atomic_uint32 hgfsHandleCounter = {0};
 
-/*
- * Number of outstanding asynchronous operations.
- */
-static Atomic_uint32 gHgfsAsyncCounter = {0};
-static MXUserExclLock *gHgfsAsyncLock;
-static MXUserCondVar  *gHgfsAsyncVar;
-
 static HgfsServerMgrCallbacks *gHgfsMgrData = NULL;
 
 
@@ -273,6 +266,8 @@ typedef struct HgfsSharedFolderProperties {
 
 
 /* Allocate/Add sessions helper functions. */
+static void
+HgfsServerAsyncInfoIncCount(HgfsAsyncRequestInfo *info);
 
 static Bool
 HgfsServerAllocateSession(HgfsTransportSessionInfo *transportSession,
@@ -355,6 +350,7 @@ HgfsServerTransportGetDefaultSession(HgfsTransportSessionInfo *transportSession,
                                      HgfsSessionInfo **session);
 static Bool HgfsPacketSend(HgfsPacket *packet,
                            HgfsTransportSessionInfo *transportSession,
+                           HgfsSessionInfo *session,
                            HgfsSendFlags flags);
 
 /*
@@ -3236,7 +3232,10 @@ HgfsServerCompleteRequest(HgfsInternalStatus status,   // IN: Status of the requ
       goto exit;
    }
 
-   if (!HgfsPacketSend(input->packet, input->transportSession, 0)) {
+   if (!HgfsPacketSend(input->packet,
+                       input->transportSession,
+                       input->session,
+                       0)) {
       /* Send failed. Drop the reply. */
       Log("%s: Error sending reply\n", __FUNCTION__);
    }
@@ -3354,7 +3353,7 @@ HgfsServerSessionReceive(HgfsPacket *packet,      // IN: Hgfs Packet
              */
             HSPU_PutMetaPacket(packet, transportSession->channelCbTable);
             input->request = NULL;
-            Atomic_Inc(&gHgfsAsyncCounter);
+            HgfsServerAsyncInfoIncCount(&input->session->asyncRequestsInfo);
 
             /* Remove pending requests during poweroff. */
             Poll_Callback(POLL_CS_MAIN,
@@ -3918,17 +3917,9 @@ HgfsServer_InitState(const HgfsServerCallbacks **callbackTable,   // IN/OUT: our
     * Initialize the globals for handling the active shared folders.
     */
 
-   gHgfsAsyncLock = NULL;
-   gHgfsAsyncVar = NULL;
-   Atomic_Write(&gHgfsAsyncCounter, 0);
-
    DblLnkLst_Init(&gHgfsSharedFoldersList);
    gHgfsSharedFoldersLock = MXUser_CreateExclLock("sharedFoldersLock",
                                                   RANK_hgfsSharedFolders);
-   gHgfsAsyncLock = MXUser_CreateExclLock("asyncLock",
-                                          RANK_hgfsSharedFolders);
-
-   gHgfsAsyncVar = MXUser_CreateCondVarExclLock(gHgfsAsyncLock);
 
    if (!HgfsPlatformInit()) {
       LOG(4, ("Could not initialize server platform specific \n"));
@@ -3998,16 +3989,6 @@ HgfsServer_ExitState(void)
       gHgfsSharedFoldersLock = NULL;
    }
 
-   if (NULL != gHgfsAsyncLock) {
-      MXUser_DestroyExclLock(gHgfsAsyncLock);
-      gHgfsAsyncLock = NULL;
-   }
-
-   if (NULL != gHgfsAsyncVar) {
-      MXUser_DestroyCondVar(gHgfsAsyncVar);
-      gHgfsAsyncVar = NULL;
-   }
-
    HgfsPlatformDestroy();
 
    /*
@@ -4417,6 +4398,170 @@ HgfsServerTransportExit(HgfsTransportSessionInfo *transportSession)   // IN: tra
 }
 
 
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * HgfsServerAsyncInfoInit --
+ *
+ *    Initialize the async request info for a session.
+ *
+ *
+ * Results:
+ *    None.
+ *
+ * Side effects:
+ *    None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+HgfsServerAsyncInfoInit(HgfsAsyncRequestInfo *info) // IN/OUT: info
+{
+   Atomic_Write(&info->requestCount, 0);
+   info->lock  = MXUser_CreateExclLock("asyncLock",
+                                       RANK_hgfsSharedFolders);
+   info->requestCountIsZero = MXUser_CreateCondVarExclLock(info->lock);
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * HgfsServerAsyncInfoExit --
+ *
+ *    Destroy the async request info for a session session.
+ *
+ *
+ * Results:
+ *    None.
+ *
+ * Side effects:
+ *    None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+HgfsServerAsyncInfoExit(HgfsAsyncRequestInfo *info) // IN/OUT: info
+{
+   ASSERT(Atomic_Read(&info->requestCount) == 0);
+   if (NULL != info->lock) {
+      MXUser_DestroyExclLock(info->lock);
+      info->lock = NULL;
+   }
+
+   if (NULL != info->requestCountIsZero) {
+      MXUser_DestroyCondVar(info->requestCountIsZero);
+      info->requestCountIsZero = NULL;
+   }
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * HgfsServerAsyncWaitForAllRequestsDone --
+ *
+ *    Wait for all the async info requests to be done.
+ *
+ *
+ * Results:
+ *    None.
+ *
+ * Side effects:
+ *    None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+HgfsServerAsyncWaitForAllRequestsDone(HgfsAsyncRequestInfo *info) // IN: info
+{
+   MXUser_AcquireExclLock(info->lock);
+   while (Atomic_Read(&info->requestCount)) {
+      MXUser_WaitCondVarExclLock(info->lock, info->requestCountIsZero);
+   }
+   MXUser_ReleaseExclLock(info->lock);
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * HgfsServerAsyncSignalAllRequestsDone --
+ *
+ *    Signal that all the async info requests are done.
+ *
+ *
+ * Results:
+ *    None.
+ *
+ * Side effects:
+ *    None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+HgfsServerAsyncSignalAllRequestsDone(HgfsAsyncRequestInfo *info) // IN: info
+{
+   MXUser_AcquireExclLock(info->lock);
+   MXUser_BroadcastCondVar(info->requestCountIsZero);
+   MXUser_ReleaseExclLock(info->lock);
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * HgfsServerAsyncInfoDecCount --
+ *
+ *    Decrement the async info request count for a session.
+ *
+ *
+ * Results:
+ *    None.
+ *
+ * Side effects:
+ *    None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+HgfsServerAsyncInfoDecCount(HgfsAsyncRequestInfo *info) // IN/OUT: info
+{
+   if (Atomic_ReadDec32(&info->requestCount) == 1) {
+      HgfsServerAsyncSignalAllRequestsDone(info);
+   }
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * HgfsServerAsyncInfoIncCount --
+ *
+ *    Increment the async info request count for a session.
+ *
+ *
+ * Results:
+ *    None.
+ *
+ * Side effects:
+ *    None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+HgfsServerAsyncInfoIncCount(HgfsAsyncRequestInfo *info) // IN/OUT: info
+{
+   Atomic_Inc(&info->requestCount);
+}
+
+
 /*
  *-----------------------------------------------------------------------------
  *
@@ -4512,6 +4657,8 @@ HgfsServerAllocateSession(HgfsTransportSessionInfo *transportSession, // IN:
       DblLnkLst_LinkLast(&session->searchFreeList,
                          &session->searchArray[i].links);
    }
+   /* Initialize the async request info.*/
+   HgfsServerAsyncInfoInit(&session->asyncRequestsInfo);
 
    /* Get common to all sessions capabiities. */
    HgfsServerGetDefaultCapabilities(session->hgfsSessionCapabilities,
@@ -4753,6 +4900,9 @@ HgfsServerExitSessionInternal(HgfsSessionInfo *session)    // IN: session contex
    MXUser_DestroyExclLock(session->searchArrayLock);
    MXUser_DestroyExclLock(session->fileIOLock);
 
+   /* Teardown the async request info.*/
+   HgfsServerAsyncInfoExit(&session->asyncRequestsInfo);
+
    free(session);
 }
 
@@ -4887,15 +5037,7 @@ HgfsServerSessionQuiesce(void *clientData,         // IN: transport and session
             HgfsNotify_Deactivate(HGFS_NOTIFY_REASON_SERVER_SYNC, session);
          }
 
-         /*
-          * XXX - TODO move these globals into the session!
-          * Wait for outstanding asynchronous requests to complete.
-          */
-         MXUser_AcquireExclLock(gHgfsAsyncLock);
-         while (Atomic_Read(&gHgfsAsyncCounter)) {
-            MXUser_WaitCondVarExclLock(gHgfsAsyncLock, gHgfsAsyncVar);
-         }
-         MXUser_ReleaseExclLock(gHgfsAsyncLock);
+         HgfsServerAsyncWaitForAllRequestsDone(&session->asyncRequestsInfo);
          break;
 
       case HGFS_QUIESCE_THAW:
@@ -4918,35 +5060,6 @@ HgfsServerSessionQuiesce(void *clientData,         // IN: transport and session
 }
 
 
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsNotifyPacketSent --
- *
- *    Decrements counter of outstanding asynchronous packets
- *    and signal conditional variable when the counter
- *    becomes 0.
- *
- * Results:
- *    TRUE on success, FALSE on error.
- *
- * Side effects:
- *    None.
- *
- *----------------------------------------------------------------------------
- */
-
-static void
-HgfsNotifyPacketSent(void)
-{
-   if (Atomic_ReadDec32(&gHgfsAsyncCounter) == 1) {
-      MXUser_AcquireExclLock(gHgfsAsyncLock);
-      MXUser_BroadcastCondVar(gHgfsAsyncVar);
-      MXUser_ReleaseExclLock(gHgfsAsyncLock);
-   }
-}
-
-
 /*
  *----------------------------------------------------------------------------
  *
@@ -4964,12 +5077,13 @@ HgfsNotifyPacketSent(void)
  */
 
 static Bool
-HgfsPacketSend(HgfsPacket *packet,            // IN/OUT: Hgfs Packet
-               HgfsTransportSessionInfo *transportSession,      // IN: session info
-               HgfsSendFlags flags)           // IN: flags for how to process
+HgfsPacketSend(HgfsPacket *packet,                         // IN/OUT: Hgfs Packet
+               HgfsTransportSessionInfo *transportSession, // IN: transport
+               HgfsSessionInfo *session,                   // IN: session info
+               HgfsSendFlags flags)                        // IN: send flags
 {
    Bool result = FALSE;
-   Bool notificationNeeded = (0 != (packet->state & HGFS_STATE_CLIENT_REQUEST) &&
+   Bool asyncClientRequest = (0 != (packet->state & HGFS_STATE_CLIENT_REQUEST) &&
                               0 != (packet->state & HGFS_STATE_ASYNC_REQUEST));
 
    ASSERT(packet);
@@ -4982,8 +5096,9 @@ HgfsPacketSend(HgfsPacket *packet,            // IN/OUT: Hgfs Packet
                                                       flags);
    }
 
-   if (notificationNeeded) {
-      HgfsNotifyPacketSent();
+   if (asyncClientRequest) {
+      ASSERT(session);
+      HgfsServerAsyncInfoDecCount(&session->asyncRequestsInfo);
    }
    return result;
 }
@@ -9218,7 +9333,10 @@ HgfsServerNotifyReceiveEventCb(HgfsSharedFolderHandle sharedFolder, // IN: share
       goto exit;
    }
 
-   if (!HgfsPacketSend(packet, session->transportSession, 0)) {
+   if (!HgfsPacketSend(packet,
+                       session->transportSession,
+                       session,
+                       0)) {
       LOG(4, ("%s: failed to send notification to the host\n", __FUNCTION__));
       goto exit;
    }
index f7b61074ecb00003abf1f4a2657fc505091af96a..7aff024596a52720b333bd3dc3bba43415169451 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * Copyright (C) 1998-2016 VMware, Inc. All rights reserved.
+ * Copyright (C) 1998-2017 VMware, Inc. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published
@@ -299,6 +299,13 @@ typedef enum {
    HGFS_SESSION_STATE_CLOSED,
 } HgfsSessionInfoState;
 
+typedef struct HgfsAsyncRequestInfo {
+   /* Asynchronous request handling. */
+   Atomic_uint32   requestCount;
+   MXUserExclLock *lock;
+   MXUserCondVar  *requestCountIsZero;
+} HgfsAsyncRequestInfo;
+
 typedef struct HgfsSessionInfo {
 
    DblLnkLst_Links links;
@@ -377,6 +384,8 @@ typedef struct HgfsSessionInfo {
 
    uint32 numberOfCapabilities;
 
+   /* Asynchronous request handling. */
+   HgfsAsyncRequestInfo  asyncRequestsInfo;
 } HgfsSessionInfo;
 
 /*