]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Hgfs OSX Server: Create and use server callback table for change notifications
authorOliver Kurth <okurth@vmware.com>
Fri, 15 Sep 2017 18:23:52 +0000 (11:23 -0700)
committerOliver Kurth <okurth@vmware.com>
Fri, 15 Sep 2017 18:23:52 +0000 (11:23 -0700)
There are now three different callbacks into the Hgfs server from the file
change notification component. So we now pass these in a table to the nofify
module when it is initialized instead of ad hoc. Previously, the same
callback is passed for every subscriber watch event and therefore duplicated
and stored in each subscriber.

Note that the feature is currently switched off by default until these changes
are complete. A user will explicitly have to enable the VMX file setting and
would cause a VMX assert to be triggered.

Details:
- The server now creates a table for its notification callbacks and passes
  it to the notify initialization function.
- The server now includes the async thread registration callbacks previously
  ifdef'd out.
- The Notify_Init function APIs are updated to reflect the new argument for
  callbacks.
- The HgfsNotify_AddSubscriber argument does not include the callback as it
  is now passed once at the initialization time.
- The HgfsNotifyEventReceiveCb type has been modified now it is an entry in
  the callback table.
- The subscriber callback function call is now validated to be non-NULL
  before calling.
- The Mac notify module adds the server callback table to its FS event
  context which is passed to the event generating submodule for the Mac
  implementation.
- The Mac notify module adds its own FS event callbacks for thread register
  and unregister called from the FS event module when registering and
  unregistering its FS event thread.

open-vm-tools/lib/hgfsServer/hgfsDirNotify.h
open-vm-tools/lib/hgfsServer/hgfsDirNotifyStub.c
open-vm-tools/lib/hgfsServer/hgfsServer.c

index 44bc4aa10f60c971e2ecb2ef763eed5df072b1cc..4fe9daeefbb4392eee6bbeeb80d1d84f2599a3d8 100644 (file)
@@ -49,13 +49,22 @@ typedef enum {
    HGFS_NOTIFY_REASON_SUBSCRIBERS,
 } HgfsNotifyActivateReason;
 
-/* This is a callback that is implemented in hgfsServer.c */
-typedef void HgfsNotifyEventReceiveCb(HgfsSharedFolderHandle sharedFolder,
-                                      HgfsSubscriberHandle subscriber,
-                                      char *name,
-                                      uint32 mask,
-                                      struct HgfsSessionInfo *session);
-HgfsInternalStatus HgfsNotify_Init(void);
+/* These are the callbacks that are implemented in hgfsServer.c */
+typedef void (*HgfsNotifyRegisterThreadCb)(struct HgfsSessionInfo *session);
+typedef void (*HgfsNotifyUnregisterThreadCb)(struct HgfsSessionInfo *session);
+typedef void (*HgfsNotifyEventReceiveCb)(HgfsSharedFolderHandle sharedFolder,
+                                         HgfsSubscriberHandle subscriber,
+                                         char *name,
+                                         uint32 mask,
+                                         struct HgfsSessionInfo *session);
+
+typedef struct HgfsServerNotifyCallbacks {
+   HgfsNotifyRegisterThreadCb     registerThread;
+   HgfsNotifyUnregisterThreadCb   unregisterThread;
+   HgfsNotifyEventReceiveCb       eventReceive;
+} HgfsServerNotifyCallbacks;
+
+HgfsInternalStatus HgfsNotify_Init(const HgfsServerNotifyCallbacks *serverCbData);
 void HgfsNotify_Exit(void);
 void HgfsNotify_Deactivate(HgfsNotifyActivateReason mode,
                            struct HgfsSessionInfo *session);
@@ -68,7 +77,6 @@ HgfsSubscriberHandle HgfsNotify_AddSubscriber(HgfsSharedFolderHandle sharedFolde
                                               const char *path,
                                               uint32 eventFilter,
                                               uint32 recursive,
-                                              HgfsNotifyEventReceiveCb notify,
                                               struct HgfsSessionInfo *session);
 
 Bool HgfsNotify_RemoveSharedFolder(HgfsSharedFolderHandle sharedFolder);
index 1b558727bea8e2d1b64663e7a27004e71ccb98df..4ce325ff58f1602819b22a5c61d0fe1475a48a20 100644 (file)
@@ -50,7 +50,7 @@
  */
 
 HgfsInternalStatus
-HgfsNotify_Init(void)
+HgfsNotify_Init(const HgfsServerNotifyCallbacks *serverCbData) // IN: serverCbData unused
 {
    return HGFS_ERROR_NOT_SUPPORTED;
 }
@@ -172,7 +172,6 @@ HgfsNotify_AddSubscriber(HgfsSharedFolderHandle sharedFolder, // IN: shared fold
                          const char *path,                    // IN: relative path
                          uint32 eventFilter,                  // IN: event filter
                          uint32 recursive,                    // IN: look in subfolders
-                         HgfsNotifyEventReceiveCb eventCb,    // IN notification callback
                          struct HgfsSessionInfo *session)     // IN: server context
 {
    return HGFS_INVALID_SUBSCRIBER_HANDLE;
index e008ea42edd6550ddc0b9a5e30c7a7e43317a0c8..5d6660e99622e7875d3e6013b734dfd740316372 100644 (file)
@@ -245,6 +245,24 @@ static const HgfsServerCallbacks gHgfsServerCBTable = {
    },
 };
 
+
+static void HgfsServerNotifyRegisterThreadCb(struct HgfsSessionInfo *session);
+static void HgfsServerNotifyUnregisterThreadCb(struct HgfsSessionInfo *session);
+static void HgfsServerNotifyReceiveEventCb(HgfsSharedFolderHandle sharedFolder,
+                                           HgfsSubscriberHandle subscriber,
+                                           char* fileName,
+                                           uint32 mask,
+                                           struct HgfsSessionInfo *session);
+
+/*
+ * Callback table passed to the directory change notification component.
+ */
+static const HgfsServerNotifyCallbacks gHgfsServerNotifyCBTable = {
+   HgfsServerNotifyRegisterThreadCb,
+   HgfsServerNotifyUnregisterThreadCb,
+   HgfsServerNotifyReceiveEventCb,
+};
+
 /* Lock that protects shared folders list. */
 static MXUserExclLock *gHgfsSharedFoldersLock = NULL;
 
@@ -340,11 +358,6 @@ static Bool HgfsHandle2NotifyInfo(HgfsHandle handle,
                                   char **fileName,
                                   size_t *fileNameSize,
                                   HgfsSharedFolderHandle *folderHandle);
-static void HgfsServerNotifyReceiveEventCb(HgfsSharedFolderHandle sharedFolder,
-                                           HgfsSubscriberHandle subscriber,
-                                           char* fileName,
-                                           uint32 mask,
-                                           struct HgfsSessionInfo *session);
 static void HgfsFreeSearchDirents(HgfsSearch *search);
 
 static HgfsInternalStatus
@@ -3932,7 +3945,7 @@ HgfsServer_InitState(const HgfsServerCallbacks **callbackTable,   // IN/OUT: our
       *callbackTable = &gHgfsServerCBTable;
 
       if (0 != (gHgfsCfgSettings.flags & HGFS_CONFIG_NOTIFY_ENABLED)) {
-         gHgfsDirNotifyActive = HgfsNotify_Init() == HGFS_STATUS_SUCCESS;
+         gHgfsDirNotifyActive = HgfsNotify_Init(&gHgfsServerNotifyCBTable) == HGFS_STATUS_SUCCESS;
          Log("%s: initialized notification %s.\n", __FUNCTION__,
              (gHgfsDirNotifyActive ? "active" : "inactive"));
       }
@@ -7828,7 +7841,7 @@ HgfsServerSetDirWatchByHandle(HgfsInputParam *input,         // IN: Input params
       LOG(4, ("%s: adding a subscriber on shared folder handle %#x\n", __FUNCTION__,
                sharedFolder));
       *watchId = HgfsNotify_AddSubscriber(sharedFolder, fileName, events, watchTree,
-                                          HgfsServerNotifyReceiveEventCb, input->session);
+                                          input->session);
       status = (HGFS_INVALID_SUBSCRIBER_HANDLE == *watchId) ? HGFS_ERROR_INTERNAL :
                                                               HGFS_ERROR_SUCCESS;
       LOG(4, ("%s: result of add subscriber id %"FMT64"x status %u\n", __FUNCTION__,
@@ -7915,7 +7928,7 @@ HgfsServerSetDirWatchByName(HgfsInputParam *input,         // IN: Input params
                LOG(8, ("%s: session %p id %"FMT64"x on share hnd %#x\n", __FUNCTION__,
                        input->session, input->session->sessionId, sharedFolder));
                *watchId = HgfsNotify_AddSubscriber(sharedFolder, tempBuf, events,
-                                                   watchTree, HgfsServerNotifyReceiveEventCb,
+                                                   watchTree,
                                                    input->session);
                status = (HGFS_INVALID_SUBSCRIBER_HANDLE == *watchId) ?
                         HGFS_ERROR_INTERNAL : HGFS_ERROR_SUCCESS;
@@ -7929,12 +7942,11 @@ HgfsServerSetDirWatchByName(HgfsInputParam *input,         // IN: Input params
          } else {
             LOG(8, ("%s: adding subscriber on share hnd %#x\n", __FUNCTION__, sharedFolder));
             *watchId = HgfsNotify_AddSubscriber(sharedFolder, "", events, watchTree,
-                                                HgfsServerNotifyReceiveEventCb,
                                                 input->session);
             status = (HGFS_INVALID_SUBSCRIBER_HANDLE == *watchId) ? HGFS_ERROR_INTERNAL :
                                                                     HGFS_ERROR_SUCCESS;
-            LOG(8, ("%s: adding subscriber on share hnd %#x result %u\n", __FUNCTION__,
-                     sharedFolder, status));
+            LOG(8, ("%s: adding subscriber on share hnd %#x watchId %"FMT64"x result %u\n",
+                    __FUNCTION__, sharedFolder, *watchId, status));
          }
       } else if (HGFS_NAME_STATUS_INCOMPLETE_BASE == nameStatus) {
          LOG(4, ("%s: Notification for root share is not supported yet\n",
@@ -9191,7 +9203,6 @@ HgfsServerGetTargetRelativePath(const char* source,    // IN: source file name
 }
 
 
-#ifdef HGFS_NOTIFY_THREAD_REGISTER_SUPPORTED
 /*
  *-----------------------------------------------------------------------------
  *
@@ -9219,6 +9230,8 @@ HgfsServerNotifyRegisterThreadCb(struct HgfsSessionInfo *session)     // IN: ses
    ASSERT(session);
    transportSession = session->transportSession;
 
+   LOG(4, ("%s: Registering thread on session %"FMT64"x\n", __FUNCTION__, session->sessionId));
+
    if (transportSession->channelCbTable->registerThread != NULL) {
       transportSession->channelCbTable->registerThread();
    }
@@ -9252,11 +9265,12 @@ HgfsServerNotifyUnregisterThreadCb(struct HgfsSessionInfo *session)     // IN: s
    ASSERT(session);
    transportSession = session->transportSession;
 
+   LOG(4, ("%s: Unregistering thread on session %"FMT64"x\n", __FUNCTION__, session->sessionId));
+
    if (transportSession->channelCbTable->unregisterThread != NULL) {
       transportSession->channelCbTable->unregisterThread();
    }
 }
-#endif // HGFS_NOTIFY_THREAD_REGISTER_SUPPORTED
 
 
 /*