]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Internal branch sync. Included in this change:
authorVMware, Inc <>
Thu, 17 Dec 2009 22:50:00 +0000 (14:50 -0800)
committerMarcelo Vanzin <mvanzin@vmware.com>
Thu, 17 Dec 2009 22:50:00 +0000 (14:50 -0800)
. Start using lib/lock, a new user-level lock library that supports lock ranks.

. Change desktop background color when in Unity mode to light gray (not yet
  implemented on X11).

. Remove lib/sync (replaced with lib/lock).

. Sync up vmxnet3 with upstreamed driver: Use API provided by Linux wherever
  possible.

. Changes in shared code that don't affect open-vm-tools functionality.

Signed-off-by: Marcelo Vanzin <mvanzin@vmware.com>
43 files changed:
open-vm-tools/configure.ac
open-vm-tools/lib/Makefile.am
open-vm-tools/lib/hgfsServer/hgfsServer.c
open-vm-tools/lib/hgfsServer/hgfsServerInt.h
open-vm-tools/lib/hgfsServer/hgfsServerLinux.c
open-vm-tools/lib/include/foundryThreads.h
open-vm-tools/lib/include/log.h
open-vm-tools/lib/include/mutex.h [new file with mode: 0644]
open-vm-tools/lib/include/syncMutex.h
open-vm-tools/lib/include/userlock.h [new file with mode: 0644]
open-vm-tools/lib/include/vcpuid.h [new file with mode: 0644]
open-vm-tools/lib/include/vix.h
open-vm-tools/lib/include/vm_basic_defs.h
open-vm-tools/lib/include/vm_basic_types.h
open-vm-tools/lib/include/vm_version.h
open-vm-tools/lib/include/vmci_sockets.h
open-vm-tools/lib/include/vthread.h [new file with mode: 0644]
open-vm-tools/lib/include/vthreadBase.h [new file with mode: 0644]
open-vm-tools/lib/lock/Makefile.am [new file with mode: 0644]
open-vm-tools/lib/lock/ul.c [new file with mode: 0644]
open-vm-tools/lib/lock/ulAcquire.c [new file with mode: 0644]
open-vm-tools/lib/lock/ulCreate.c [new file with mode: 0644]
open-vm-tools/lib/lock/ulDestroy.c [new file with mode: 0644]
open-vm-tools/lib/lock/ulInt.h [new file with mode: 0644]
open-vm-tools/lib/lock/ulIsLocked.c [new file with mode: 0644]
open-vm-tools/lib/lock/ulRWPosix.c [new file with mode: 0644]
open-vm-tools/lib/lock/ulRelease.c [new file with mode: 0644]
open-vm-tools/lib/lock/ulSingleton.c [new file with mode: 0644]
open-vm-tools/lib/lock/ulTryAcquire.c [new file with mode: 0644]
open-vm-tools/lib/nothread/Makefile.am [new file with mode: 0644]
open-vm-tools/lib/nothread/vthreadUL.c [new file with mode: 0644]
open-vm-tools/lib/sync/syncMutexPthread.c
open-vm-tools/lib/unity/unity.c
open-vm-tools/lib/unity/unityPlatform.h
open-vm-tools/lib/unity/unityPlatformX11.c
open-vm-tools/lib/user/utilPosix.c
open-vm-tools/libvmtools/Makefile.am
open-vm-tools/modules/linux/vmxnet/vmxnet.c
open-vm-tools/modules/linux/vmxnet3/vmxnet3_drv.c
open-vm-tools/modules/shared/vmxnet/npa_defs.h
open-vm-tools/modules/shared/vmxnet/vmxnet3_defs.h
open-vm-tools/toolbox/Makefile.am
open-vm-tools/vmware-user/Makefile.am

index a72ee7a46ef1fc18b0f24f23871c8c580fdf0a8f..f6456c646838d122e774d1247d05aec6913a9118 100644 (file)
@@ -1182,7 +1182,9 @@ AC_SUBST([LIB_AUTH_CPPFLAGS])
 AC_SUBST([LIB_FILE_CPPFLAGS])
 AC_SUBST([LIB_HGFS_SERVER_CPPFLAGS])
 AC_SUBST([LIB_IMPERSONATE_CPPFLAGS])
+AC_SUBST([LIB_LOCK_CPPFLAGS])
 AC_SUBST([LIB_MISC_CPPFLAGS])
+AC_SUBST([LIB_NOTHREAD_CPPFLAGS])
 AC_SUBST([LIB_PROC_MGR_CPPFLAGS])
 AC_SUBST([LIB_STRING_CPPFLAGS])
 AC_SUBST([LIB_USER_CPPFLAGS])
@@ -1225,9 +1227,11 @@ AC_CONFIG_FILES([                      \
    lib/hgfsServerPolicyGuest/Makefile  \
    lib/image/Makefile                  \
    lib/impersonate/Makefile            \
+   lib/lock/Makefile                   \
    lib/message/Makefile                \
    lib/misc/Makefile                   \
    lib/netUtil/Makefile                \
+   lib/nothread/Makefile               \
    lib/panic/Makefile                  \
    lib/panicDefault/Makefile           \
    lib/printer/Makefile                \
index 48686181003dde750f9309dae6ef9c8c5cd44d0c..974c77cf3bc3796838d8f8fd8414919f8851f090 100644 (file)
@@ -50,9 +50,11 @@ if ENABLE_UNITY
    SUBDIRS += image
 endif
 SUBDIRS += impersonate
+SUBDIRS += lock
 SUBDIRS += message
 SUBDIRS += misc
 SUBDIRS += netUtil
+SUBDIRS += nothread
 SUBDIRS += panic
 SUBDIRS += panicDefault
 SUBDIRS += printer
index eca7852472b295a7458df9fee887bcd41e7f1ac3..fa2bd7b4fae12e8b5ba2b621026bb67206489d09 100644 (file)
@@ -30,7 +30,7 @@
 #include "file.h"
 #include "util.h"
 #include "wiper.h"
-#include "syncMutex.h"
+#include "userlock.h"
 #include "hgfsDirNotify.h"
 
 #if defined(_WIN32)
@@ -495,7 +495,7 @@ HgfsHandle2FileDesc(HgfsHandle handle,        // IN: Hgfs file handle
    Bool found = FALSE;
    HgfsFileNode *fileNode = NULL;
 
-   SyncMutex_Lock(&session->nodeArrayLock);
+   MXUser_AcquireExclLock(session->nodeArrayLock);
    fileNode = HgfsHandle2FileNode(handle, session);
    if (fileNode == NULL) {
       goto exit;
@@ -508,7 +508,7 @@ HgfsHandle2FileDesc(HgfsHandle handle,        // IN: Hgfs file handle
    found = TRUE;
 
 exit:
-   SyncMutex_Unlock(&session->nodeArrayLock);
+   MXUser_ReleaseExclLock(session->nodeArrayLock);
 
    return found;
 }
@@ -540,7 +540,7 @@ HgfsHandle2AppendFlag(HgfsHandle handle,        // IN: Hgfs file handle
    Bool found = FALSE;
    HgfsFileNode *fileNode = NULL;
 
-   SyncMutex_Lock(&session->nodeArrayLock);
+   MXUser_AcquireExclLock(session->nodeArrayLock);
    fileNode = HgfsHandle2FileNode(handle, session);
    if (fileNode == NULL) {
       goto exit;
@@ -550,7 +550,7 @@ HgfsHandle2AppendFlag(HgfsHandle handle,        // IN: Hgfs file handle
    found = TRUE;
 
 exit:
-   SyncMutex_Unlock(&session->nodeArrayLock);
+   MXUser_ReleaseExclLock(session->nodeArrayLock);
 
    return found;
 }
@@ -584,7 +584,7 @@ HgfsHandle2LocalId(HgfsHandle handle,        // IN: Hgfs file handle
 
    ASSERT(localId);
 
-   SyncMutex_Lock(&session->nodeArrayLock);
+   MXUser_AcquireExclLock(session->nodeArrayLock);
    fileNode = HgfsHandle2FileNode(handle, session);
    if (fileNode == NULL) {
       goto exit;
@@ -596,7 +596,7 @@ HgfsHandle2LocalId(HgfsHandle handle,        // IN: Hgfs file handle
    found = TRUE;
 
 exit:
-   SyncMutex_Unlock(&session->nodeArrayLock);
+   MXUser_ReleaseExclLock(session->nodeArrayLock);
 
    return found;
 }
@@ -632,7 +632,7 @@ HgfsHandle2ServerLock(HgfsHandle handle,        // IN: Hgfs file handle
 
    ASSERT(lock);
 
-   SyncMutex_Lock(&session->nodeArrayLock);
+   MXUser_AcquireExclLock(session->nodeArrayLock);
    fileNode = HgfsHandle2FileNode(handle, session);
    if (fileNode == NULL) {
       goto exit;
@@ -642,7 +642,7 @@ HgfsHandle2ServerLock(HgfsHandle handle,        // IN: Hgfs file handle
    found = TRUE;
 
 exit:
-   SyncMutex_Unlock(&session->nodeArrayLock);
+   MXUser_ReleaseExclLock(session->nodeArrayLock);
 
    return found;
 #else
@@ -681,7 +681,8 @@ HgfsFileDesc2Handle(fileDesc fd,              // IN: OS handle (file descriptor)
    ASSERT(session);
    ASSERT(session->nodeArray);
 
-   SyncMutex_Lock(&session->nodeArrayLock);
+   MXUser_AcquireExclLock(session->nodeArrayLock);
+
    for (i = 0; i < session->numNodes; i++) {
       existingFileNode = &session->nodeArray[i];
       if ((existingFileNode->state == FILENODE_STATE_IN_USE_CACHED) &&
@@ -692,7 +693,7 @@ HgfsFileDesc2Handle(fileDesc fd,              // IN: OS handle (file descriptor)
       }
    }
 
-   SyncMutex_Unlock(&session->nodeArrayLock);
+   MXUser_ReleaseExclLock(session->nodeArrayLock);
 
    return found;
 }
@@ -728,7 +729,8 @@ HgfsHandle2ShareMode(HgfsHandle handle,         // IN: Hgfs file handle
       return found;
    }
 
-   SyncMutex_Lock(&session->nodeArrayLock);
+   MXUser_AcquireExclLock(session->nodeArrayLock);
+
    existingFileNode = HgfsHandle2FileNode(handle, session);
    if (existingFileNode == NULL) {
       goto exit_unlock;
@@ -740,7 +742,8 @@ HgfsHandle2ShareMode(HgfsHandle handle,         // IN: Hgfs file handle
    found = (nameStatus == HGFS_NAME_STATUS_COMPLETE);
 
 exit_unlock:
-   SyncMutex_Unlock(&session->nodeArrayLock);
+   MXUser_ReleaseExclLock(session->nodeArrayLock);
+
    return found;
 }
 
@@ -808,7 +811,8 @@ HgfsHandle2FileNameMode(HgfsHandle handle,       // IN: Hgfs file handle
       return found;
    }
 
-   SyncMutex_Lock(&session->nodeArrayLock);
+   MXUser_AcquireExclLock(session->nodeArrayLock);
+
    existingFileNode = HgfsHandle2FileNode(handle, session);
    if (existingFileNode == NULL) {
       goto exit_unlock;
@@ -826,9 +830,11 @@ HgfsHandle2FileNameMode(HgfsHandle handle,       // IN: Hgfs file handle
    found = TRUE;
 
 exit_unlock:
-   SyncMutex_Unlock(&session->nodeArrayLock);
+   MXUser_ReleaseExclLock(session->nodeArrayLock);
+
    *fileName = name;
    *fileNameSize = nameSize;
+
    return found;
 }
 
@@ -866,7 +872,8 @@ HgfsFileHasServerLock(const char *utf8Name,             // IN: Name in UTF8
    ASSERT(session);
    ASSERT(session->nodeArray);
 
-   SyncMutex_Lock(&session->nodeArrayLock);
+   MXUser_AcquireExclLock(session->nodeArrayLock);
+
    for (i = 0; i < session->numNodes; i++) {
       HgfsFileNode *existingFileNode = &session->nodeArray[i];
       if ((existingFileNode->state == FILENODE_STATE_IN_USE_CACHED) &&
@@ -880,7 +887,8 @@ HgfsFileHasServerLock(const char *utf8Name,             // IN: Name in UTF8
       }
    }
 
-   SyncMutex_Unlock(&session->nodeArrayLock);
+   MXUser_ReleaseExclLock(session->nodeArrayLock);
+
    return found;
 #else
    return FALSE;
@@ -918,7 +926,8 @@ HgfsGetNodeCopy(HgfsHandle handle,        // IN: Hgfs file handle
 
    ASSERT(copy);
 
-   SyncMutex_Lock(&session->nodeArrayLock);
+   MXUser_AcquireExclLock(session->nodeArrayLock);
+
    original = HgfsHandle2FileNode(handle, session);
    if (original == NULL) {
       goto exit;
@@ -948,7 +957,8 @@ HgfsGetNodeCopy(HgfsHandle handle,        // IN: Hgfs file handle
    found = TRUE;
 
 exit:
-   SyncMutex_Unlock(&session->nodeArrayLock);
+   MXUser_ReleaseExclLock(session->nodeArrayLock);
+
    return found;
 }
 
@@ -980,7 +990,8 @@ HgfsHandleIsSequentialOpen(HgfsHandle handle,        // IN:  Hgfs file handle
 
    ASSERT(sequentialOpen);
 
-   SyncMutex_Lock(&session->nodeArrayLock);
+   MXUser_AcquireExclLock(session->nodeArrayLock);
+
    node = HgfsHandle2FileNode(handle, session);
    if (node == NULL) {
       goto exit;
@@ -990,7 +1001,8 @@ HgfsHandleIsSequentialOpen(HgfsHandle handle,        // IN:  Hgfs file handle
    success = TRUE;
 
 exit:
-   SyncMutex_Unlock(&session->nodeArrayLock);
+   MXUser_ReleaseExclLock(session->nodeArrayLock);
+
    return success;
 }
 
@@ -1022,7 +1034,8 @@ HgfsHandleIsSharedFolderOpen(HgfsHandle handle,        // IN:  Hgfs file handle
 
    ASSERT(sharedFolderOpen);
 
-   SyncMutex_Lock(&session->nodeArrayLock);
+   MXUser_AcquireExclLock(session->nodeArrayLock);
+
    node = HgfsHandle2FileNode(handle, session);
    if (node == NULL) {
       goto exit;
@@ -1032,7 +1045,8 @@ HgfsHandleIsSharedFolderOpen(HgfsHandle handle,        // IN:  Hgfs file handle
    success = TRUE;
 
 exit:
-   SyncMutex_Unlock(&session->nodeArrayLock);
+   MXUser_ReleaseExclLock(session->nodeArrayLock);
+
    return success;
 }
 
@@ -1064,7 +1078,8 @@ HgfsUpdateNodeFileDesc(HgfsHandle handle,        // IN: Hgfs file handle
    HgfsFileNode *node;
    Bool updated = FALSE;
 
-   SyncMutex_Lock(&session->nodeArrayLock);
+   MXUser_AcquireExclLock(session->nodeArrayLock);
+
    node = HgfsHandle2FileNode(handle, session);
    if (node == NULL) {
       goto exit;
@@ -1075,7 +1090,8 @@ HgfsUpdateNodeFileDesc(HgfsHandle handle,        // IN: Hgfs file handle
    updated = TRUE;
 
 exit:
-   SyncMutex_Unlock(&session->nodeArrayLock);
+   MXUser_ReleaseExclLock(session->nodeArrayLock);
+
    return updated;
 }
 
@@ -1110,7 +1126,8 @@ HgfsUpdateNodeServerLock(fileDesc fd,                // IN: OS handle
    ASSERT(session);
    ASSERT(session->nodeArray);
 
-   SyncMutex_Lock(&session->nodeArrayLock);
+   MXUser_AcquireExclLock(session->nodeArrayLock);
+
    for (i = 0; i < session->numNodes; i++) {
       existingFileNode = &session->nodeArray[i];
       if (existingFileNode->state != FILENODE_STATE_UNUSED) {
@@ -1122,7 +1139,8 @@ HgfsUpdateNodeServerLock(fileDesc fd,                // IN: OS handle
       }
    }
 
-   SyncMutex_Unlock(&session->nodeArrayLock);
+   MXUser_ReleaseExclLock(session->nodeArrayLock);
+
    return updated;
 }
 
@@ -1152,7 +1170,8 @@ HgfsUpdateNodeAppendFlag(HgfsHandle handle,        // IN: Hgfs file handle
    HgfsFileNode *node;
    Bool updated = FALSE;
 
-   SyncMutex_Lock(&session->nodeArrayLock);
+   MXUser_AcquireExclLock(session->nodeArrayLock);
+
    node = HgfsHandle2FileNode(handle, session);
    if (node == NULL) {
       goto exit;
@@ -1164,7 +1183,8 @@ HgfsUpdateNodeAppendFlag(HgfsHandle handle,        // IN: Hgfs file handle
    updated = TRUE;
 
 exit:
-   SyncMutex_Unlock(&session->nodeArrayLock);
+   MXUser_ReleaseExclLock(session->nodeArrayLock);
+
    return updated;
 }
 
@@ -1507,9 +1527,9 @@ static void
 HgfsFreeFileNode(HgfsHandle handle,         // IN: Handle to free
                  HgfsSessionInfo *session)  // IN: Session info
 {
-   SyncMutex_Lock(&session->nodeArrayLock);
+   MXUser_AcquireExclLock(session->nodeArrayLock);
    HgfsFreeFileNodeInternal(handle, session);
-   SyncMutex_Unlock(&session->nodeArrayLock);
+   MXUser_ReleaseExclLock(session->nodeArrayLock);
 }
 
 
@@ -1854,9 +1874,9 @@ HgfsIsServerLockAllowed(HgfsSessionInfo *session)  // IN: session info
 {
    Bool allowed;
 
-   SyncMutex_Lock(&session->nodeArrayLock);
+   MXUser_AcquireExclLock(session->nodeArrayLock);
    allowed = session->numCachedLockedNodes < MAX_LOCKED_FILENODES;
-   SyncMutex_Unlock(&session->nodeArrayLock);
+   MXUser_ReleaseExclLock(session->nodeArrayLock);
 
    return allowed;
 }
@@ -2053,7 +2073,7 @@ HgfsGetSearchCopy(HgfsHandle handle,        // IN: Hgfs search handle
 
    ASSERT(copy);
 
-   SyncMutex_Lock(&session->searchArrayLock);
+   MXUser_AcquireExclLock(session->searchArrayLock);
    original = HgfsSearchHandle2Search(handle, session);
    if (original == NULL) {
       goto exit;
@@ -2084,7 +2104,7 @@ HgfsGetSearchCopy(HgfsHandle handle,        // IN: Hgfs search handle
    found = TRUE;
 
 exit:
-   SyncMutex_Unlock(&session->searchArrayLock);
+   MXUser_ReleaseExclLock(session->searchArrayLock);
 
    return found;
 }
@@ -2236,13 +2256,15 @@ HgfsRemoveSearch(HgfsHandle handle,        // IN: search
    HgfsSearch *search;
    Bool success = FALSE;
 
-   SyncMutex_Lock(&session->searchArrayLock);
+   MXUser_AcquireExclLock(session->searchArrayLock);
+
    search = HgfsSearchHandle2Search(handle, session);
    if (search != NULL) {
       HgfsRemoveSearchInternal(search, session);
       success = TRUE;
    }
-   SyncMutex_Unlock(&session->searchArrayLock);
+
+   MXUser_ReleaseExclLock(session->searchArrayLock);
 
    return success;
 }
@@ -2276,7 +2298,8 @@ HgfsGetSearchResult(HgfsHandle handle,         // IN: Handle to search
    HgfsSearch *search;
    DirectoryEntry *dent = NULL;
 
-   SyncMutex_Lock(&session->searchArrayLock);
+   MXUser_AcquireExclLock(session->searchArrayLock);
+
    search = HgfsSearchHandle2Search(handle, session);
    if (search == NULL || search->dents == NULL) {
       goto out;
@@ -2332,7 +2355,7 @@ HgfsGetSearchResult(HgfsHandle handle,         // IN: Handle to search
    }
 
   out:
-   SyncMutex_Unlock(&session->searchArrayLock);
+   MXUser_ReleaseExclLock(session->searchArrayLock);
 
    return dent;
 }
@@ -2416,7 +2439,8 @@ HgfsUpdateNodeNames(const char *oldLocalName,  // IN: Name of file to look for
 
    newBufferLen = strlen(newLocalName);
 
-   SyncMutex_Lock(&session->nodeArrayLock);
+   MXUser_AcquireExclLock(session->nodeArrayLock);
+
    for (i = 0; i < session->numNodes; i++) {
       fileNode = &session->nodeArray[i];
 
@@ -2440,7 +2464,8 @@ HgfsUpdateNodeNames(const char *oldLocalName,  // IN: Name of file to look for
          fileNode->utf8NameLen = newBufferLen;
       }
    }
-   SyncMutex_Unlock(&session->nodeArrayLock);
+
+   MXUser_ReleaseExclLock(session->nodeArrayLock);
 }
 
 
@@ -2888,22 +2913,30 @@ HgfsServerSessionConnect(void *transportData,        // IN: transport session co
     * Initialize all our locks first as these can fail.
     */
 
-   if (!SyncMutex_Init(&session->fileIOLock, NULL)) {
+   session->fileIOLock = MXUser_CreateExclLock("HgfsFileIOLock",
+                                               RANK_UNRANKED);
+   if (session->fileIOLock == NULL) {
       free(session);
       LOG(4, ("%s: Could not create node array sync mutex.\n", __FUNCTION__));
 
       return FALSE;
    }
-   if (!SyncMutex_Init(&session->nodeArrayLock, NULL)) {
-      SyncMutex_Destroy(&session->fileIOLock);
+
+   session->nodeArrayLock = MXUser_CreateExclLock("HgfsNodeArrayLock",
+                                                  RANK_UNRANKED);
+   if (session->nodeArrayLock == NULL) {
+      MXUser_DestroyExclLock(session->fileIOLock);
       free(session);
       LOG(4, ("%s: Could not create node array sync mutex.\n", __FUNCTION__));
 
       return FALSE;
    }
-   if (!SyncMutex_Init(&session->searchArrayLock, NULL)) {
-      SyncMutex_Destroy(&session->fileIOLock);
-      SyncMutex_Destroy(&session->nodeArrayLock);
+
+   session->searchArrayLock = MXUser_CreateExclLock("HgfsSearchArrayLock",
+                                                    RANK_UNRANKED);
+   if (session->searchArrayLock == NULL) {
+      MXUser_DestroyExclLock(session->fileIOLock);
+      MXUser_DestroyExclLock(session->nodeArrayLock);
       free(session);
       LOG(4, ("%s: Could not create search array sync mutex.\n", __FUNCTION__));
 
@@ -3030,7 +3063,6 @@ HgfsServerSessionClose(void *clientData)    // IN: session context
 
    /* Remove, typically, the last reference, will teardown everything. */
    HgfsServerSessionPut(session);
-
 }
 
 
@@ -3063,7 +3095,7 @@ HgfsServerExitSessionInternal(HgfsSessionInfo *session)    // IN: session contex
    ASSERT(session->nodeArray);
    ASSERT(session->searchArray);
 
-   SyncMutex_Lock(&session->nodeArrayLock);
+   MXUser_AcquireExclLock(session->nodeArrayLock);
 
    LOG(4, ("%s: exiting.\n", __FUNCTION__));
    /* Recycle all nodes that are still in use, then destroy the node pool. */
@@ -3081,10 +3113,14 @@ HgfsServerExitSessionInternal(HgfsSessionInfo *session)    // IN: session contex
    free(session->nodeArray);
    session->nodeArray = NULL;
 
-   SyncMutex_Unlock(&session->nodeArrayLock);
+   MXUser_ReleaseExclLock(session->nodeArrayLock);
 
-   /* Recycle all searches that are still in use, then destroy the search pool. */
-   SyncMutex_Lock(&session->searchArrayLock);
+   /*
+    * Recycle all searches that are still in use, then destroy the
+    * search pool.
+    */
+
+   MXUser_AcquireExclLock(session->searchArrayLock);
 
    for (i = 0; i < session->numSearches; i++) {
       if (DblLnkLst_IsLinked(&session->searchArray[i].links)) {
@@ -3095,12 +3131,12 @@ HgfsServerExitSessionInternal(HgfsSessionInfo *session)    // IN: session contex
    free(session->searchArray);
    session->searchArray = NULL;
 
-   SyncMutex_Unlock(&session->searchArrayLock);
+   MXUser_ReleaseExclLock(session->searchArrayLock);
 
    /* Teardown the locks for the sessions and destroy itself. */
-   SyncMutex_Destroy(&session->nodeArrayLock);
-   SyncMutex_Destroy(&session->searchArrayLock);
-   SyncMutex_Destroy(&session->fileIOLock);
+   MXUser_DestroyExclLock(session->nodeArrayLock);
+   MXUser_DestroyExclLock(session->searchArrayLock);
+   MXUser_DestroyExclLock(session->fileIOLock);
    free(session);
 }
 
@@ -3365,7 +3401,7 @@ HgfsInvalidateSessionObjects(DblLnkLst_Links *shares,  // IN: List of new shares
    LOG(4, ("%s: Beginning\n", __FUNCTION__));
 
 
-   SyncMutex_Lock(&session->nodeArrayLock);
+   MXUser_AcquireExclLock(session->nodeArrayLock);
 
    /*
     * Iterate over each node, skipping those that are unused. For each node,
@@ -3407,9 +3443,9 @@ HgfsInvalidateSessionObjects(DblLnkLst_Links *shares,  // IN: List of new shares
       }
    }
 
-   SyncMutex_Unlock(&session->nodeArrayLock);
+   MXUser_ReleaseExclLock(session->nodeArrayLock);
 
-   SyncMutex_Lock(&session->searchArrayLock);
+   MXUser_AcquireExclLock(session->searchArrayLock);
 
    /*
     * Iterate over each search, skipping those that are on the free list. For
@@ -3446,7 +3482,7 @@ HgfsInvalidateSessionObjects(DblLnkLst_Links *shares,  // IN: List of new shares
       }
    }
 
-   SyncMutex_Unlock(&session->searchArrayLock);
+   MXUser_ReleaseExclLock(session->searchArrayLock);
 
    LOG(4, ("%s: Ending\n", __FUNCTION__));
 }
@@ -3904,7 +3940,8 @@ HgfsServerDumpDents(HgfsHandle searchHandle,  // IN: Handle to dump dents from
    unsigned int i;
    HgfsSearch *search;
 
-   SyncMutex_Lock(&session->searchArrayLock);
+   MXUser_AcquireExclLock(session->searchArrayLock);
+
    search = HgfsSearchHandle2Search(searchHandle, session);
    if (search != NULL) {
       Log("%s: %u dents in \"%s\"\n", __FUNCTION__, search->numDents,
@@ -3915,7 +3952,8 @@ HgfsServerDumpDents(HgfsHandle searchHandle,  // IN: Handle to dump dents from
          Log("\"%s\"\n", search->dents[i]->d_name);
       }
    }
-   SyncMutex_Unlock(&session->searchArrayLock);
+
+   MXUser_ReleaseExclLock(session->searchArrayLock);
 #endif
 }
 
@@ -4125,7 +4163,8 @@ HgfsServerSearchRealDir(char const *baseDir,      // IN: Directory to search
    ASSERT(handle);
    ASSERT(shareName);
 
-   SyncMutex_Lock(&session->searchArrayLock);
+   MXUser_AcquireExclLock(session->searchArrayLock);
+
    search = HgfsAddNewSearch(baseDir, DIRECTORY_SEARCH_TYPE_DIR, shareName,
                              rootDir, session);
    if (!search) {
@@ -4159,7 +4198,7 @@ HgfsServerSearchRealDir(char const *baseDir,      // IN: Directory to search
    *handle = HgfsSearch2SearchHandle(search);
 
   out:
-   SyncMutex_Unlock(&session->searchArrayLock);
+   MXUser_ReleaseExclLock(session->searchArrayLock);
 
    return status;
 }
@@ -4202,7 +4241,8 @@ HgfsServerSearchVirtualDir(HgfsGetNameFunc *getName,     // IN: Name enumerator
    ASSERT(cleanupName);
    ASSERT(handle);
 
-   SyncMutex_Lock(&session->searchArrayLock);
+   MXUser_AcquireExclLock(session->searchArrayLock);
+
    search = HgfsAddNewSearch("", type, "", "", session);
    if (!search) {
       LOG(4, ("%s: failed to get new search\n", __FUNCTION__));
@@ -4222,7 +4262,7 @@ HgfsServerSearchVirtualDir(HgfsGetNameFunc *getName,     // IN: Name enumerator
    *handle = HgfsSearch2SearchHandle(search);
 
   out:
-   SyncMutex_Unlock(&session->searchArrayLock);
+   MXUser_ReleaseExclLock(session->searchArrayLock);
 
    return status;
 }
@@ -4253,9 +4293,9 @@ HgfsRemoveFromCache(HgfsHandle handle,          // IN: Hgfs handle to the node
 {
    Bool removed = FALSE;
 
-   SyncMutex_Lock(&session->nodeArrayLock);
+   MXUser_AcquireExclLock(session->nodeArrayLock);
    removed = HgfsRemoveFromCacheInternal(handle, session);
-   SyncMutex_Unlock(&session->nodeArrayLock);
+   MXUser_ReleaseExclLock(session->nodeArrayLock);
 
    return removed;
 }
@@ -4284,9 +4324,9 @@ HgfsIsCached(HgfsHandle handle,         // IN: Structure representing file node
 {
    Bool cached = FALSE;
 
-   SyncMutex_Lock(&session->nodeArrayLock);
+   MXUser_AcquireExclLock(session->nodeArrayLock);
    cached = HgfsIsCachedInternal(handle, session);
-   SyncMutex_Unlock(&session->nodeArrayLock);
+   MXUser_ReleaseExclLock(session->nodeArrayLock);
 
    return cached;
 }
@@ -4394,9 +4434,9 @@ HgfsAddToCache(HgfsHandle handle,        // IN: HGFS file handle
 {
    Bool added = FALSE;
 
-   SyncMutex_Lock(&session->nodeArrayLock);
+   MXUser_AcquireExclLock(session->nodeArrayLock);
    added = HgfsAddToCacheInternal(handle, session);
-   SyncMutex_Unlock(&session->nodeArrayLock);
+   MXUser_ReleaseExclLock(session->nodeArrayLock);
 
    return added;
 }
@@ -4459,13 +4499,14 @@ HgfsCreateAndCacheFileNode(HgfsFileOpenInfo *openInfo, // IN: Open info struct
       sharedFolderOpen = TRUE;
    }
 
-   SyncMutex_Lock(&session->nodeArrayLock);
+   MXUser_AcquireExclLock(session->nodeArrayLock);
+
    node = HgfsAddNewFileNode(openInfo, localId, fileDesc, append, len,
                              openInfo->cpName, sharedFolderOpen, session);
 
    if (node == NULL) {
       LOG(4, ("%s: Failed to add new node.\n", __FUNCTION__));
-      SyncMutex_Unlock(&session->nodeArrayLock);
+      MXUser_ReleaseExclLock(session->nodeArrayLock);
 
       return FALSE;
    }
@@ -4473,11 +4514,12 @@ HgfsCreateAndCacheFileNode(HgfsFileOpenInfo *openInfo, // IN: Open info struct
 
    if (!HgfsAddToCacheInternal(handle, session)) {
       LOG(4, ("%s: Failed to add node to the cache.\n", __FUNCTION__));
-      SyncMutex_Unlock(&session->nodeArrayLock);
+      MXUser_ReleaseExclLock(session->nodeArrayLock);
 
       return FALSE;
    }
-   SyncMutex_Unlock(&session->nodeArrayLock);
+
+   MXUser_ReleaseExclLock(session->nodeArrayLock);
 
    /* Only after everything is successful, save the handle in the open info. */
    openInfo->file = handle;
index dc27d5d90ddb06b1bb42850c1b3877d2b10b5673..eb7ba5d3d0a88886d902989db666a60b9d6eefdf 100644 (file)
@@ -73,7 +73,7 @@
 #include "cpName.h"     // for HgfsNameStatus
 #include "hgfsServerPolicy.h"
 #include "hgfsUtil.h"   // for HgfsInternalStatus
-#include "syncMutex.h"
+#include "userlock.h"
 
 /*
  * Does this platform have oplock support? We define it here to avoid long
@@ -285,7 +285,7 @@ typedef struct HgfsSessionInfo {
    HgfsSessionSendFunc *send;
 
    /* Lock to ensure some fileIO requests are atomic for a handle. */
-   SyncMutex fileIOLock;
+   MXUserExclLock *fileIOLock;
 
    Atomic_uint32 refCount;    /* Reference count for session. */
 
@@ -295,7 +295,7 @@ typedef struct HgfsSessionInfo {
     * Lock for the following 6 fields: the node array,
     * counters and lists for this session.
     */
-   SyncMutex nodeArrayLock;
+   MXUserExclLock *nodeArrayLock;
 
    /* Open file nodes of this session. */
    HgfsFileNode *nodeArray;
@@ -322,7 +322,7 @@ typedef struct HgfsSessionInfo {
     * Lock for the following three fields: for the search array
     * and it's counter and list, for this session.
     */
-   SyncMutex searchArrayLock;
+   MXUserExclLock *searchArrayLock;
 
    /* Directory entry cache for this session. */
    HgfsSearch *searchArray;
index afe624ab5199e2600452bfa433c6403c1fe28804..468588ebff33b7d751785513fa15cd3386ee93fc 100644 (file)
@@ -57,7 +57,7 @@
 #include "posix.h"
 #include "file.h"
 #include "util.h"
-#include "syncMutex.h"
+#include "userlock.h"
 #include "su.h"
 #include "codeset.h"
 #include "unicodeOperations.h"
@@ -3675,7 +3675,9 @@ HgfsServerRead(char const *packetIn,     // IN: incoming packet
     * Seek to the offset and read from the file. Grab the IO lock to make
     * this and the subsequent read atomic.
     */
-   SyncMutex_Lock(&session->fileIOLock);
+
+   MXUser_AcquireExclLock(session->fileIOLock);
+
    if (!sequentialOpen) {
 #   ifdef linux
       {
@@ -3694,13 +3696,13 @@ HgfsServerRead(char const *packetIn,     // IN: incoming packet
          status = errno;
          LOG(4, ("%s: could not seek to %"FMT64"u: %s\n", __FUNCTION__,
                  offset, strerror(status)));
-         SyncMutex_Unlock(&session->fileIOLock);
+         MXUser_ReleaseExclLock(session->fileIOLock);
          goto error;
       }
    }
 
    error = read(fd, payload, requiredSize);
-   SyncMutex_Unlock(&session->fileIOLock);
+   MXUser_ReleaseExclLock(session->fileIOLock);
 #endif
    if (error < 0) {
       status = errno;
@@ -3853,7 +3855,8 @@ HgfsServerWrite(char const *packetIn,     // IN: incoming packet
     * Seek to the offset and write from the file. Grab the IO lock to make
     * this and the subsequent write atomic.
     */
-   SyncMutex_Lock(&session->fileIOLock);
+
+   MXUser_AcquireExclLock(session->fileIOLock);
    if (!sequentialOpen) {
 #   ifdef linux
       {
@@ -3872,13 +3875,13 @@ HgfsServerWrite(char const *packetIn,     // IN: incoming packet
          status = errno;
          LOG(4, ("%s: could not seek to %"FMT64"u: %s\n", __FUNCTION__,
                  offset, strerror(status)));
-         SyncMutex_Unlock(&session->fileIOLock);
+         MXUser_ReleaseExclLock(session->fileIOLock);
          goto error;
       }
    }
 
    error = write(fd, payload, requiredSize);
-   SyncMutex_Unlock(&session->fileIOLock);
+   MXUser_ReleaseExclLock(session->fileIOLock);
 #endif
    if (error < 0) {
       status = errno;
index 0263a4eba7a22f65ed877d282faaf3d3a2d1edf7..9456e2e9fb4e122a3287e888abfaedfe69a8c07f 100644 (file)
@@ -35,6 +35,8 @@ extern "C"{
 #include <pthread.h>
 #endif
 
+#include "util.h"
+
 struct FoundryWorkerThread;
 
 typedef void (*FoundryThreadProc)(struct FoundryWorkerThread *threadState);
index deaf999e983613509fa0acf90f72d8e8483eb9bf..3b1e38d9a6e98d174f301093aaa7551d109a31d6 100644 (file)
@@ -56,7 +56,6 @@ EXTERN Bool Log_InitForApp(const char *fileName, const char *config,
 EXTERN Bool Log_InitEx(const LogInitParams *params);
 EXTERN void Log_Exit(void);
 EXTERN void Log_SetConfigDir(const char *configDir);
-EXTERN void Log_SetLockFunc(void (*f)(Bool locking));
 EXTERN void Log_WriteLogFile(const char *msg);
 
 EXTERN Bool Log_Enabled(void);
diff --git a/open-vm-tools/lib/include/mutex.h b/open-vm-tools/lib/include/mutex.h
new file mode 100644 (file)
index 0000000..2d1b81c
--- /dev/null
@@ -0,0 +1,547 @@
+/*********************************************************
+ * Copyright (C) 2000 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
+ * by the Free Software Foundation version 2.1 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the Lesser GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
+ *
+ *********************************************************/
+
+#ifndef _MUTEX_H_
+#define _MUTEX_H_
+
+#define INCLUDE_ALLOW_VMMEXT
+#define INCLUDE_ALLOW_USERLEVEL
+#define INCLUDE_ALLOW_VMCORE
+#include "includeCheck.h"
+
+#ifdef _WIN32
+#include <WTypes.h> // for HANDLE
+#endif
+
+#include "vm_atomic.h"
+#include "vthread.h"
+#if defined VMM && defined VMCORE
+#include "mon_types.h"
+#include "x86regname.h"
+#endif
+
+#if defined VMM || defined VMX86_VMX
+#include "vprobe_static.h"
+#define VMM_VMX_ONLY(x) x
+#else
+#define VMM_VMX_ONLY(x)
+#endif
+
+/*
+ * mutex.h --
+ *
+ * This is the header file for mutual exclusion locks ("mutexes"). 
+ * These locks can be used by both monitor and user level code. 
+ *
+ * We provide two variants: regular locks and recursive locks. The
+ * latter can be reacquired by the owning thread, in a counting manner.
+ *
+ * In optimized builds, locks are minimal and fast. In debug builds,
+ * we maintain additional information to catch improper use of locks.
+ *
+ */
+
+/* If adjusting MX_MAX_LOCKS, also adjust VMK's RPC_MAX_WORLD_CONNECTIONS. */
+#define MX_MAX_LOCKS             160 /* Max # of locks supported */ 
+#define MX_MAX_NAME_LEN          16  /* Max lock/condvar name len incl. zero. */
+
+/* 
+ * On linux, semaphore use a pipe for waiting/waking up. If the pipe fills 
+ * up, a thread doing a V() can block, which is not very nice. Which is
+ * why we cap the number of signals that a semaphore can accumulate.
+ */ 
+
+#define MX_MAX_SEMASIGNALS       64  /* Max #of accumulated signals in a counting sema. */
+
+typedef uint32 MX_LockID;
+typedef uint8  MXCVLink;
+
+typedef struct MXCVQueue {
+   MXCVLink head;
+   MXCVLink tail;
+   uint8    nsigs;
+   uint8    nwaits;   
+} MXCVQueue;
+
+typedef union MXCVWord {             /* Private to this module. */
+   uint32        all;
+   Atomic_uint32 atomic;
+   MXCVQueue     s;
+} MXCVWord;
+
+/*
+ * The detail-level of stats collection is compile-time selectable. 
+ *   0: no stats collected
+ *   1: samples lock usage at each timer tick
+ *   2: count blocking/nonblocking lock operations
+ *   3: like level 2, but additionally collect call chains.
+ * The defaults for the various builds are: obj = 2, opt = 1, others = 0
+ * Lock stats are currently disabled for opt builds. Will reenable soon.
+ */
+
+#if defined VMX86_VMX || defined VMM
+#define MX_STATS_LEVEL \
+    (vmx86_stats ? (vmx86_debug ? 2 : 1) : 0)
+#else
+#define MX_STATS_LEVEL 0
+#endif
+
+#if MX_STATS_LEVEL > 0
+#define MX_STATS_ONLY(x) x
+#else
+#define MX_STATS_ONLY(x)
+#endif
+
+/* When we compile with debugging or lock stats, we include extra fields. */
+#define MX_FAT_LOCKS (vmx86_debug || MX_STATS_LEVEL > 1)
+
+#if MX_FAT_LOCKS != 0
+#define MX_FAT_LOCKS_ONLY(x) x
+#else
+#define MX_FAT_LOCKS_ONLY(x)
+#endif
+
+/*
+ * For 64-bit Windows, the single 64-bit semaphore handle is spread
+ * across waitHandle (lower half) and signalHandle (upper half). For
+ * 32-bit Windows, the single 32-bit semaphore handle is stored in
+ * waitHandle. POSIX platforms use two 32-bit fds, waitHandle and
+ * signalHandle.
+ *
+ * #ifdefs and unions are avoided here because of offsetChecker
+ * limitations and padding issues. Wrapper functions for Windows
+ * provide get/set access to the handle.
+ */
+
+typedef struct MXSemaphore {
+   int           waitHandle;
+   int           signalHandle;
+   Atomic_uint32 signalled;
+   uint32        pad;
+#if MX_FAT_LOCKS != 0
+   uint64        blockTime;
+#endif
+} MXSemaphore;
+
+/* 
+ * Although we define these types in a public header file, code 
+ * in other modules should never access the lock fields directly. 
+ */
+
+typedef struct MX_Mutex {
+   Atomic_uint32   nthreads; /* #threads interested in lock; incl. owner.    */
+   MX_LockID       lid;      /* Unique id of lock; set at lock init time.    */
+   MX_Rank         rank;     /* Rank of this lock; immutable.                */
+   uint32          _pad;     /* pad to 8-byte boundary.                      */
+#if MX_FAT_LOCKS != 0
+   Bool            tracing;  /* True iff tracing is enabled for this lock.   */
+   VThreadID       owner;    /* Thread that currently holds lock (if any).   
+                              * Only used for assertion purposes. */
+   uint64          ip;       /* R/EIP where lock was acquired.               */
+#endif
+} MX_Mutex;
+
+typedef struct MX_MutexRec {
+   MX_Mutex        lck;      /* The core lock in this recursive mutex.       */
+   VThreadID       owner;    /* Owner thr. if lock held; else invalid id.    */
+   unsigned        count;    /* Number of times currently locked.            */
+} MX_MutexRec;
+
+typedef struct MX_Condvar {
+   MXCVWord      cvword;     /* Semantics private to this module. */
+#if MX_FAT_LOCKS != 0
+   char          name[MX_MAX_NAME_LEN]; /* Zero-terminated name for condvar. */
+#endif
+} MX_Condvar;
+
+typedef struct MX_Barrier {
+   MX_Mutex   lck;           /* Lock that protects barrier state.            */
+   MX_Condvar cv;            /* Threads wait here for barrier to saturate.   */
+   unsigned   threshold;     /* Barrier threshold; set at init time only.    */
+   unsigned   nEntered;      /* Number of threads that have reached barrier. */
+   MX_FAT_LOCKS_ONLY(uint32 _pad;)
+} MX_Barrier;
+
+typedef struct MX_BinSemaphore {
+   MXSemaphore   sema;
+   MX_Rank       rank;
+   Atomic_uint32 signalled;
+#if MX_FAT_LOCKS != 0
+   char          name[MX_MAX_NAME_LEN]; /* Name of binary semaphore. */
+#endif
+} MX_BinSemaphore;
+
+typedef struct MX_CountingSemaphore {
+   MXSemaphore   sema;
+   MX_Rank       rank;
+   uint32        _pad;
+#if MX_FAT_LOCKS != 0
+   char          name[MX_MAX_NAME_LEN]; /* Name of counting semaphore. */
+#endif
+} MX_CountingSemaphore;
+
+#if MX_STATS_LEVEL > 0
+EXTERN MX_Mutex *curLock;
+EXTERN void MXInitLockStats(const char *name, MX_Mutex *lck);
+#else
+#define MXInitLockStats(name, lck)
+#endif
+
+#if MX_STATS_LEVEL > 1
+EXTERN void MX_LogStats(unsigned epoch);
+#else
+#define MX_LogStats(epoch)
+#endif
+
+#if MX_FAT_LOCKS != 0
+EXTERN void MXInitLockFat(const char *name, MX_Rank rank, MX_Mutex *lck);
+EXTERN void MXAcquiredLock(MX_Mutex *lck, Bool blocking);
+EXTERN void MX_AssertNoLocksHeld(Bool checkPendingLocks);
+EXTERN void MXInitCondvarFat(const char *name, MX_Condvar *cv);
+EXTERN void MX_CheckRank(MX_Rank rank, const char *name);
+EXTERN void MX_CheckRankWithBULL(MX_MutexRec *lock, Bool belowUser);
+EXTERN Bool MX_IsLockedByThread(const MX_Mutex *lck, VThreadID tid);
+EXTERN Bool MX_IsLockedByCurThread(const MX_Mutex *lck);
+EXTERN MX_Rank MX_CurrentRank(void);
+#else
+/* Use macros to keep string arguments out of release builds. */
+#define MXInitLockFat(name, rank, lck)
+#define MXAcquiredLock(lck, blocking)
+#define MX_AssertNoLocksHeld(checkPendingLocks)
+#define MXInitCondvarFat(name, cv)
+#define MX_CheckRank(rank, name)
+#define MX_CheckRankWithBULL(lock, belowUser)
+#endif
+
+EXTERN void MXInitLockWork(MX_Mutex *lck, MX_Rank rank);
+EXTERN size_t MX_GetMXStateSize(void);
+EXTERN void MX_Init(void *mxStatePtr);
+EXTERN void MX_PlantThreadWatchDog(void (*func)(void));
+EXTERN void MX_InitPerThread(VThreadID tid);
+EXTERN void MX_ExitPerThread(VThreadID tid);
+EXTERN void MX_Shutdown(void);
+EXTERN void MX_Lock(MX_Mutex *lck);
+EXTERN void MX_Unlock(MX_Mutex *lck);
+EXTERN void MX_DestroyLock(MX_Mutex *lck);
+EXTERN void MX_LockRec(MX_MutexRec *lckr);
+EXTERN void MX_UnlockRec(MX_MutexRec *lckr);
+EXTERN Bool MX_TryLockRec(MX_MutexRec *lckr);
+EXTERN Bool MX_IsLockedByThreadRec(const MX_MutexRec *lckr, VThreadID tid);
+EXTERN Bool MX_IsLockedByCurThreadRec(const MX_MutexRec *lckr);
+EXTERN void MXInitCondvarWork(MX_Condvar *cv);
+EXTERN void MX_Signal(MX_Condvar *cv);
+EXTERN void MX_Broadcast(MX_Condvar *cv);
+EXTERN void MX_Wait(MX_Condvar *cv, MX_Mutex *lck);
+EXTERN void MX_WaitRec(MX_Condvar *cv, MX_MutexRec *lckr);
+EXTERN void MX_InitBarrier(MX_Barrier *br, MX_Rank rank, unsigned threshold);
+EXTERN void MX_EnterBarrier(MX_Barrier *br);
+#if !defined VMM
+EXTERN Bool MX_WaitTimeout(MX_Condvar *cv, MX_Mutex *lck, int maxWaitUS);
+EXTERN Bool MX_WaitRecTimeout(MX_Condvar *cv, MX_MutexRec *lckr, int maxWaitUS);
+#endif
+
+EXTERN void MX_InitBinSemaphore(const char *name, MX_Rank rank, MX_BinSemaphore *binSema);
+EXTERN MXSemaHandle MX_BinSemaphoreGetSemaHandle(MX_BinSemaphore *binSema);
+#ifdef _WIN32
+EXTERN void MX_BinSemaphoreSetSemaHandle(MX_BinSemaphore *binSema, MXSemaHandle h);
+#endif
+EXTERN void MX_DestroyBinSemaphore(MX_BinSemaphore *binSema);
+EXTERN void MX_BinSemaphoreWait(MX_BinSemaphore *binSema);
+#if !defined VMM
+EXTERN Bool MX_BinSemaphoreTryWaitTimeout(MX_BinSemaphore *binSema, int usTimeout);
+#endif
+EXTERN void MX_BinSemaphoreSignal(MX_BinSemaphore *binSema);
+EXTERN Bool MX_BinSemaphoreTryWait(MX_BinSemaphore *binSema);
+EXTERN void MX_InitCountingSemaphore(const char *name, MX_Rank rank, MX_CountingSemaphore *csema);
+EXTERN void MX_DestroyCountingSemaphore(MX_CountingSemaphore *csema);
+EXTERN void MX_CountingSemaphoreWait(MX_CountingSemaphore *csema);
+EXTERN void MX_CountingSemaphoreSignal(MX_CountingSemaphore *csema);
+EXTERN Bool MX_CountingSemaphoreTryWait(MX_CountingSemaphore *csema);
+
+#if defined VMM
+#ifdef VMX86_DEBUG
+EXTERN Bool prohibitBarriers;
+#endif
+EXTERN void MX_LockMarkEnd(void);
+EXTERN void MX_UnlockMarkEnd(void);
+#if defined VMCORE
+EXTERN void MX_LockCalloutStart(void);
+EXTERN void MX_LockCalloutEnd(void);
+EXTERN TCA  MX_LockEmit(MX_Mutex *lck, TCA memptr);
+EXTERN TCA  MX_UnlockEmit(MX_Mutex *lck, TCA memptr);
+EXTERN TCA  MX_LockIndEmit(RegisterName reg, TCA memptr);
+EXTERN TCA  MX_UnlockIndEmit(RegisterName reg, TCA memptr);
+EXTERN TCA  MX_LockRecEmit(MX_MutexRec *lck, TCA memptr);
+EXTERN TCA  MX_UnlockRecEmit(MX_MutexRec *lck, TCA memptr);
+EXTERN Bool MX_VCPUNeedsForceWakeup(Vcpuid vcpuid);
+EXTERN void MX_SemaphoreForceWakeup(Vcpuid vcpuid);
+#endif
+#else
+EXTERN Bool MX_PowerOn(void);
+EXTERN void MX_PowerOff(void);
+EXTERN Bool MX_IsInitialized(void);
+#endif
+
+
+/*
+ *----------------------------------------------------------------------
+ * MX_InitLock --
+ *    Initialize a lock. 
+ *    Use macros to keep strings out of release builds.
+ *    Types: const char *name, MX_Rank rank, MX_Mutex *lck.
+ *----------------------------------------------------------------------
+ */
+
+#define MX_InitLock(name, rank, lck)                                          \
+   do {                                                                       \
+      MX_Mutex *_lck = (lck);                                                 \
+                                                                              \
+      /* Use two fcts to make name dead in release builds. */                 \
+      MXInitLockWork(_lck, rank);                                             \
+      MXInitLockFat((name), (rank), _lck);                                    \
+      MXInitLockStats((name), _lck);                                          \
+   } while (0)
+
+
+/*
+ *----------------------------------------------------------------------
+ * MX_IsLocked --
+ *    Return TRUE iff "lck" is currently locked by some thread.
+ *    Since this is an unstable property, except when it is known that
+ *    the current thread holds the lock, this operation is mostly useful
+ *    to assert that a lock is held (by the current thread).
+ *----------------------------------------------------------------------
+ */
+
+static INLINE Bool
+MX_IsLocked(MX_Mutex *lck)  // IN:
+{ 
+   return Atomic_Read(&lck->nthreads) != 0;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ * MX_TryLock --
+ *    Try to get a lock, but don't block if it is unavailable.
+ *    Return TRUE if lock was successfully acquired, FALSE otherwise.
+ *----------------------------------------------------------------------
+ */
+
+static INLINE Bool
+MX_TryLock(MX_Mutex *lck)  // IN:
+{
+   /* This code was written to produce good code for MX_Lock(). 
+      If you change it, be sure to inspect the generated code. */
+   uint32 old = Atomic_ReadIfEqualWrite(&lck->nthreads, 0, 1);
+
+   if (old == 0) {
+#if MX_FAT_LOCKS != 0 
+      {
+         lck->ip = (uint64)(uintptr_t) GetReturnAddress();
+      }
+#endif
+      MXAcquiredLock(lck, FALSE);
+      VMM_VMX_ONLY(VProbe_2Args(VPROBE_MX_LockAcquired, lck->lid, lck->rank));
+   }
+
+   return old == 0;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ * MX_SetTracing --
+ *    Enable or disable tracing of activity on a lock. 
+ *    No-op in non-debug builds.
+ *----------------------------------------------------------------------
+ */
+
+static INLINE void 
+MX_SetTracing(MX_Mutex *lck,  // IN:
+              Bool t)         // IN:
+{
+   DEBUG_ONLY(lck->tracing = t);
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ * MX_InitLockRec --
+ *    Initialize a recursive lock.
+ *    Use macros to keep strings out of release builds.
+ *    Types: const char *name, MX_Rank rank, MX_MutexRec *lckr
+ *----------------------------------------------------------------------
+ */
+
+#define MX_InitLockRec(name, rank, lckr)                                      \
+   do {                                                                       \
+      MX_MutexRec *_lckr = (lckr);                                            \
+      MX_InitLock((name), (rank), &_lckr->lck);                               \
+      _lckr->owner = VTHREAD_INVALID_ID;                                      \
+      _lckr->count = 0;                                                       \
+   } while (0)
+
+
+/*
+ *----------------------------------------------------------------------
+ * MX_IsLockedRec --
+ *    Similar to "MX_IsLocked()" but applies to recursive locks.
+ *----------------------------------------------------------------------
+ */
+
+static INLINE Bool
+MX_IsLockedRec(MX_MutexRec *lckr)  // IN:
+{
+   return MX_IsLocked(&lckr->lck);
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ * MX_SetTracingRec --
+ *    Similar to "MX_SetTracing()" but applies to recursive locks.
+ *----------------------------------------------------------------------
+ */
+
+static INLINE void 
+MX_SetTracingRec(MX_MutexRec *lckr,  // IN:
+                 Bool t)             // IN:
+{
+   MX_SetTracing(&lckr->lck, t);
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ * MX_DestroyLockRec --
+ *    Like "MX_DestroyLock()" but applies to recursive mutex.
+ *----------------------------------------------------------------------
+ */
+
+static INLINE void 
+MX_DestroyLockRec(MX_MutexRec *lckr)  // IN:
+{ 
+   MX_DestroyLock(&lckr->lck); 
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ * MX_LockOwnerRec --
+ *    Return the lock owner, or VTHREAD_INVALID_ID.
+ *----------------------------------------------------------------------
+ */
+
+static INLINE VThreadID 
+MX_LockOwnerRec(MX_MutexRec *lckr)  // IN:
+{ 
+   return lckr->owner;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ * MX_InitCondvar --
+ *    Initialize a condition variable.
+ *    Use macro to keep strings out of release builds.
+ *    Types: const char *name, MX_Condvar *cv.
+ *----------------------------------------------------------------------
+ */
+
+#define MX_InitCondvar(name, cv)                                              \
+   do {                                                                       \
+      MX_Condvar *_cv = (cv);                                                 \
+      MXInitCondvarWork(_cv);                                                 \
+      MXInitCondvarFat((name), _cv);                                          \
+   } while (0)
+
+
+/*
+ *----------------------------------------------------------------------
+ * MX_DestroyBarrier --
+ *    Release all resources held by a barrier.
+ *----------------------------------------------------------------------
+ */
+
+static INLINE void
+MX_DestroyBarrier(MX_Barrier *br)  // IN:
+{
+   ASSERT(br->nEntered == 0);
+   MX_DestroyLock(&br->lck);
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ * MX_GetRank --
+ *    Returns a lock's rank.
+ *----------------------------------------------------------------------
+ */
+
+static INLINE MX_Rank
+MX_GetRank(MX_Mutex *lock)  // IN:
+{
+   ASSERT(lock != NULL);
+
+   return lock->rank;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ * MX_GetRankRec --
+ *    Returns a recursive lock's rank.
+ *----------------------------------------------------------------------
+ */
+
+static INLINE MX_Rank
+MX_GetRankRec(MX_MutexRec *lock)  // IN:
+{
+   ASSERT(lock != NULL);
+
+   return MX_GetRank(&lock->lck);
+}
+
+
+#if defined VMM && defined VMCORE // {
+
+EXTERN int inSemaWait;
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * MX_SemaphoreInWait --
+ *    TRUE if this vcpu is waiting on any semaphore. This is currently used by 
+ *    the poweroff code to find out whether we are holding any (partial) locks.
+ *
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static INLINE Bool
+MX_SemaphoreInWait(void)
+{
+   ASSERT(inSemaWait >= 0);
+
+   return inSemaWait > 0;
+}
+
+#endif // }
+
+#endif  // _MUTEX_H_
index d4e7f9a0185c0260ddfe5cca3d9d9f909da1b258..d53c7b582e1c61e7c9e5123e442bd2d1a926a98c 100644 (file)
@@ -71,6 +71,4 @@ Bool SyncMutex_Unlock(SyncMutex *that);
 Bool SyncMutex_Trylock(SyncMutex *that);
 #endif
 
-SyncMutex *SyncMutex_CreateSingleton(Atomic_Ptr *lckStorage);
-
 #endif // #ifndef _SYNC_MUTEX_H_
diff --git a/open-vm-tools/lib/include/userlock.h b/open-vm-tools/lib/include/userlock.h
new file mode 100644 (file)
index 0000000..9071df8
--- /dev/null
@@ -0,0 +1,104 @@
+/*********************************************************
+ * Copyright (C) 2009 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
+ * by the Free Software Foundation version 2.1 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the Lesser GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
+ *
+ *********************************************************/
+
+#ifndef _USERLOCK_H_
+#define _USERLOCK_H_
+
+#define INCLUDE_ALLOW_VMMEXT
+#define INCLUDE_ALLOW_USERLEVEL
+#define INCLUDE_ALLOW_VMCORE
+#include "includeCheck.h"
+
+#include "vm_atomic.h"
+#include "vm_basic_types.h"
+#include "vm_basic_defs.h"
+
+/*
+ * Statistics interfaces will come soon.
+ *
+ * Each lock is expected to keep:
+ *   - Min
+ *   - Max
+ *   - Mean
+ *   - S.D.
+ *   - Histogram (log2?)
+ *
+ * for time-till-acquistion and time-locked.
+ */
+
+typedef struct MXUserExclLock   MXUserExclLock;
+typedef struct MXUserRecLock    MXUserRecLock;
+typedef struct MXUserRWLock     MXUserRWLock;
+
+/*
+ * Exclusive ownership lock
+ */
+
+MXUserExclLock *
+MXUser_CreateExclLock(const char *name,
+                    MX_Rank rank);
+
+void MXUser_AcquireExclLock(MXUserExclLock *lock);
+Bool MXUser_TryAcquireExclLock(MXUserExclLock *lock);
+void MXUser_ReleaseExclLock(MXUserExclLock *lock);
+void MXUser_DestroyExclLock(MXUserExclLock *lock);
+Bool MXUser_IsLockedByCurThreadExclLock(const MXUserExclLock *lock);
+
+MXUserExclLock *
+MXUser_CreateSingletonExclLock(Atomic_Ptr *lockStorage,
+                               const char *name,
+                               MX_Rank rank);
+
+/*
+ * Recursive lock.
+ */
+
+MXUserRecLock *
+MXUser_CreateRecLock(const char *name,
+                     MX_Rank rank);
+
+void MXUser_AcquireRecLock(MXUserRecLock *lock);
+Bool MXUser_TryAcquireRecLock(MXUserRecLock *lock);
+void MXUser_ReleaseRecLock(MXUserRecLock *lock);
+void MXUser_DestroyRecLock(MXUserRecLock *lock);
+Bool MXUser_IsLockedByCurThreadRecLock(const MXUserRecLock *lock);
+
+MXUserRecLock *
+MXUser_CreateSingletonRecLock(Atomic_Ptr *lockStorage,
+                              const char *name,
+                              MX_Rank rank);
+
+/*
+ * Eventually there will be an API to bind an recursive MX lock to a
+ * MXUser recursive lock. This will allow such MXUser recursive locks
+ * to be used for Poll.
+ */
+
+/*
+ * Read-write lock
+ */
+
+MXUserRWLock *
+MXUser_CreateRWLock(const char *name,
+                    MX_Rank rank);
+
+void MXUser_AcquireForRead(MXUserRWLock *lock);
+void MXUser_AcquireForWrite(MXUserRWLock *lock);
+void MXUser_ReleaseRWLock(MXUserRWLock *lock);
+void MXUser_DestroyRWLock(MXUserRWLock *lock);
+#endif  // _USERLOCK_H_
diff --git a/open-vm-tools/lib/include/vcpuid.h b/open-vm-tools/lib/include/vcpuid.h
new file mode 100644 (file)
index 0000000..a39addf
--- /dev/null
@@ -0,0 +1,53 @@
+/*********************************************************
+ * Copyright (C) 1998-2003 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
+ * by the Free Software Foundation version 2.1 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the Lesser GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
+ *
+ *********************************************************/
+
+/*
+ *
+ * vcpuid.h --
+ *
+ *    Monitor's VCPU ID.
+ */
+
+#ifndef _VCPUID_H_
+#define _VCPUID_H_
+
+#define INCLUDE_ALLOW_USERLEVEL
+#define INCLUDE_ALLOW_VMMEXT
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_VMMON
+#define INCLUDE_ALLOW_VMKERNEL
+#define INCLUDE_ALLOW_VMK_MODULE
+#define INCLUDE_ALLOW_DISTRIBUTE
+#define INCLUDE_ALLOW_VMCORE
+#include "includeCheck.h"
+
+#include "vm_basic_types.h"
+
+
+typedef uint32 Vcpuid;                 // VCPU number
+
+#define VCPUID_INVALID (~0U)
+
+#define BOOT_VCPU_ID           0
+#define IS_BOOT_VCPUID(vcpuid)  ((vcpuid) == BOOT_VCPU_ID)
+#define IS_BOOT_VCPU()         IS_BOOT_VCPUID(CurVcpuid())
+
+#define MAX_VCPUS      32
+
+
+#endif // ifndef _VCPUID_H_
index 065f7c829a5c004197676fcdd4f173056218b350..0398141c5ebd9b14c90dd9a3ab9a3adf6d3c17aa 100644 (file)
@@ -317,6 +317,7 @@ enum {
    VIX_E_WRAPPER_VERSION_NOT_FOUND              = 22002,
    VIX_E_WRAPPER_SERVICEPROVIDER_NOT_FOUND      = 22003,
    VIX_E_WRAPPER_PLAYER_NOT_INSTALLED           = 22004,
+   VIX_E_WRAPPER_RUNTIME_NOT_INSTALLED          = 22005,
 
    /* FuseMnt errors*/
    VIX_E_MNTAPI_MOUNTPT_NOT_FOUND               = 24000,
index ab3b526808ceacc252309bacef39a144d7b2347d..329f2497552b162830c71e399ea4df51907a802f 100644 (file)
@@ -657,4 +657,13 @@ typedef int pid_t;
 #define hosted_lg_pg 0
 #endif
 
+/*
+ * Basic lock ranks.  Others are defined in mutexRank.h.
+ */
+
+#define RANK_UNRANKED            0
+#define RANK_userlevelLock       100
+#define RANK_LEAF                0xFFFE
+#define RANK_INVALID             0xFFFF
+
 #endif // ifndef _VM_BASIC_DEFS_H_
index 224655f4e50329fd88b9563b5c11e4b01585dfe5..9959d9aed2150059211b66ab3fdf9b582950c670 100644 (file)
@@ -950,6 +950,31 @@ typedef void * UserVA;
 #   endif
 #endif
 
+#ifdef __APPLE__
+/*
+ * Format specifier for all these annoying types such as {S,U}Int32
+ * which are 'long' in 32-bit builds
+ *       and  'int' in 64-bit builds.
+ */
+#   ifdef __LP64__
+#      define FMTLI ""
+#   else
+#      define FMTLI "l"
+#   endif
+
+/*
+ * Format specifier for all these annoying types such as NS[U]Integer
+ * which are  'int' in 32-bit builds
+ *       and 'long' in 64-bit builds.
+ */
+#   ifdef __LP64__
+#      define FMTIL "l"
+#   else
+#      define FMTIL ""
+#   endif
+#endif
+
+
 /*
  * Define MXSemaHandle here so both vmmon and vmx see this definition.
  */
@@ -1001,4 +1026,10 @@ typedef struct VMRect {
 } VMRect;
 #endif
 
+/*
+ * ranked locks "everywhere"
+ */
+
+typedef uint32 MX_Rank;
+
 #endif  /* _VM_BASIC_TYPES_H_ */
index 2d2f3bf2f3da164a4dc233fb9c8e765263a7b0eb..180c1bf7df495fb370aff79ac72d04c2967cbd74 100644 (file)
 #define WBC_VERSION "e.x.p"
 #define SDK_VERSION "4.1.0"
 #define FOUNDRY_VERSION "e.x.p"
-#define FOUNDRY_FILE_VERSION 1,8,0,PRODUCT_BUILD_NUMBER_NUMERIC
+#define FOUNDRY_FILE_VERSION 1,8,1,PRODUCT_BUILD_NUMBER_NUMERIC
 #define VMLS_VERSION "e.x.p"
 #define VLICENSE_VERSION "1.1.2"
 #define DDK_VERSION "e.x.p"
index 6c11aed0a9581a3ba21e86f596dad6936d5a70f3..7d00636b5869a5a21edcdded311170b9eeeb4d7b 100644 (file)
@@ -53,6 +53,7 @@
 #define SO_VMCI_BUFFER_MAX_SIZE             2
 #define SO_VMCI_PEER_HOST_VM_ID             3
 #define SO_VMCI_SERVICE_LABEL               4
+#define SO_VMCI_TRUSTED                     5
 
 /*
  * The VMCI sockets address equivalents of INADDR_ANY.  The first works for
diff --git a/open-vm-tools/lib/include/vthread.h b/open-vm-tools/lib/include/vthread.h
new file mode 100644 (file)
index 0000000..930dba0
--- /dev/null
@@ -0,0 +1,323 @@
+/*********************************************************
+ * Copyright (C) 2002 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
+ * by the Free Software Foundation version 2.1 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the Lesser GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
+ *
+ *********************************************************/
+
+/*
+ * vthread.h --
+ *
+ *     Thread management
+ */
+
+#ifndef _VTHREAD_H_
+#define _VTHREAD_H_
+
+
+#define INCLUDE_ALLOW_USERLEVEL
+#define INCLUDE_ALLOW_VMMEXT
+#define INCLUDE_ALLOW_VMCORE
+#include "includeCheck.h"
+
+#include "vthreadBase.h"
+#include "vcpuid.h"
+
+#if VTHREAD_USE_PTHREAD
+#include <sys/types.h>
+#include <unistd.h>
+#include <pthread.h>
+#endif
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+
+#if VTHREAD_MAX_VCPUS < MAX_VCPUS
+   #error VTHREAD_MAX_VCPUS < MAX_VCPUS
+#endif
+
+
+/*
+ * Scheduler priorities for VThread_SetThreadPriority().
+ */
+
+#if VTHREAD_USE_PTHREAD
+#ifdef __APPLE__
+// These values come from osfmk/kern/sched.h in xnu-792.6.70.
+#   define VTHREAD_PRIORITY_IDLE                0
+#   define VTHREAD_PRIORITY_LOWEST              11
+#   define VTHREAD_PRIORITY_BELOW_NORMAL        21
+#   define VTHREAD_PRIORITY_NORMAL              31
+#   define VTHREAD_PRIORITY_ABOVE_NORMAL        41
+#   define VTHREAD_PRIORITY_HIGHEST             51
+// TODO: This is just the highest a user thread can go; not really time critical.
+#   define VTHREAD_PRIORITY_TIME_CRITICAL       63
+#else
+#   define VTHREAD_PRIORITY_IDLE                19
+#   define VTHREAD_PRIORITY_LOWEST              15
+#   define VTHREAD_PRIORITY_BELOW_NORMAL        10
+#   define VTHREAD_PRIORITY_NORMAL              0
+#   define VTHREAD_PRIORITY_ABOVE_NORMAL       (-10)
+#   define VTHREAD_PRIORITY_HIGHEST            (-15)
+#   define VTHREAD_PRIORITY_TIME_CRITICAL      (-20)
+#endif // !__APPLE__
+#endif
+#ifdef _WIN32
+#   define VTHREAD_PRIORITY_IDLE                THREAD_PRIORITY_IDLE
+#   define VTHREAD_PRIORITY_LOWEST              THREAD_PRIORITY_LOWEST
+#   define VTHREAD_PRIORITY_BELOW_NORMAL        THREAD_PRIORITY_BELOW_NORMAL
+#   define VTHREAD_PRIORITY_NORMAL              THREAD_PRIORITY_NORMAL
+#   define VTHREAD_PRIORITY_ABOVE_NORMAL        THREAD_PRIORITY_ABOVE_NORMAL
+#   define VTHREAD_PRIORITY_HIGHEST             THREAD_PRIORITY_HIGHEST
+#   define VTHREAD_PRIORITY_TIME_CRITICAL       THREAD_PRIORITY_TIME_CRITICAL
+#endif
+
+
+/*
+ * Debuggable builds log per-thread timing info.
+ */
+
+#if (defined(VMX86_DEVEL) || defined(VMX86_DEBUG)) && defined(USERLEVEL)
+#define VTHREAD_RESOURCE_ACCOUNTING
+#endif
+
+
+/*
+ * Private variables
+ *
+ * Don't use these directly.  Go through the proper interface
+ * functions.
+ */
+
+#ifdef VMM
+extern VThreadID vthreadCurID;
+#endif
+
+extern VThreadID vthreadMaxVCPUID;
+
+
+/*
+ * Global functions
+ */
+
+static INLINE Bool
+VThread_IsValidID(VThreadID tid) // IN: The thread id.
+{
+   return tid < VTHREAD_MAX_THREADS;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * VThread_CurID --
+ *
+ *      Get the current thread ID. This is only inline for the monitor.
+ *
+ * Results:
+ *      Thread ID.
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+#ifdef VMM
+static INLINE VThreadID
+VThread_CurID(void)
+{
+   ASSERT(VThread_IsValidID(vthreadCurID));
+
+   return vthreadCurID;
+}
+#endif
+
+
+static INLINE Bool
+VThread_IsVMXID(VThreadID tid) // IN: The thread id.
+{
+   return tid == VTHREAD_VMX_ID;
+}
+
+
+static INLINE Bool
+VThread_IsMKSID(VThreadID tid) // IN: The thread id.
+{
+   return tid == VTHREAD_MKS_ID;
+}
+
+
+static INLINE Bool
+VThread_IsVCPUID(VThreadID tid) // IN: The thread id.
+{
+   ASSERT(VThread_IsValidID(vthreadMaxVCPUID));
+
+   return tid >= VTHREAD_VCPU0_ID && tid < vthreadMaxVCPUID;
+}
+
+
+static INLINE Bool
+VThread_IsVMX(void)
+{
+   return VThread_IsVMXID(VThread_CurID());
+}
+
+
+static INLINE Bool
+VThread_IsMKS(void)
+{
+   return VThread_IsMKSID(VThread_CurID());
+}
+
+
+static INLINE Bool
+VThread_IsVCPU(void)
+{
+   return VThread_IsVCPUID(VThread_CurID());
+}
+
+
+static INLINE Bool
+VThread_IsVCPU0(void)
+{
+   return VThread_CurID() == VTHREAD_VCPU0_ID;
+}
+
+
+static INLINE Vcpuid
+VThread_ThreadIDToVCPUID(VThreadID tid) // IN: The thread id.
+{
+   ASSERT(VThread_IsVCPUID(tid));
+
+   return tid - VTHREAD_VCPU0_ID;
+}
+
+
+static INLINE VThreadID
+VThread_VCPUIDToThreadID(Vcpuid vcpuID)
+{
+   VThreadID threadID = VTHREAD_VCPU0_ID + vcpuID;
+
+   ASSERT(VThread_IsVCPUID(threadID));
+
+   return threadID;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * VThread_BestVCPUID --
+ *
+ *      Return the "best" VCPU to use (for actions), which is
+ *     either the current VCPU (if any) or some default.
+ *
+ *     The monitor version needs to be a macro because of an include
+ *     problem: CurVcpuid() is defined in monitor.h, which includes
+ *     sharedAreaVCPU.h, which includes misc_shared.h,
+ *     which includes mutex.h, which includes us.
+ *
+ * Results:
+ *      The best VCPU ID.
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+#ifdef VMM
+#define VThread_BestVCPUID() CurVcpuid()
+
+#else
+#ifdef VCPUID_INVALID
+static INLINE Vcpuid
+VThread_BestVCPUID(void)
+{
+   VThreadID threadID = VThread_CurID();
+
+   return VThread_IsVCPUID(threadID) ? VThread_ThreadIDToVCPUID(threadID) :
+                                       BOOT_VCPU_ID;
+}
+#endif
+#endif
+
+
+#ifdef VMM // {
+
+/*
+ * Save a few bytes and inline VThread_MonitorInit().
+ *
+ * The VCPU ID and number of VCPU's are passed in because
+ * (it's the right thing to do, and) they require monitor.h,
+ * which includes mutex.h, which includes us.
+ * -- edward
+ */
+
+static INLINE void
+VThread_MonitorInit(Vcpuid vcpuID, int numVCPUs)
+{
+   /*
+    * Initialize vthreadMaxVCPUID first because
+    * VThread_VCPUIDToThreadID() depends on it.
+    */
+
+   vthreadMaxVCPUID = VTHREAD_VCPU0_ID + numVCPUs;
+   vthreadCurID = VThread_VCPUIDToThreadID(vcpuID);
+}
+
+#else // } {
+
+void VThread_SetNumVCPUs(int numVCPUs);
+VThreadID VThread_AllocID(void);
+Bool VThread_IsAllocatedID(VThreadID tid);
+void VThread_ReserveID(VThreadID tid);
+void VThread_FreeID(VThreadID tid);
+VThreadID VThread_CreateThread(void (*fn)(void *), void *data,
+                              VThreadID tid, const char *name);
+void VThread_DestroyThread(VThreadID tid);
+Bool VThread_IsCurrentVThreadValid(void);
+void VThread_WaitThread(VThreadID tid);
+void VThread_SetPriorityLimits(int min, int max);
+void VThread_AdjustThreadPriority(VThreadID tid, int inc, int incHighest,
+                                  int incTimeCritical);
+Bool VThread_SetThreadPriority(VThreadID tid, int newPrio);
+uintptr_t VThread_GetApproxStackTop(VThreadID tid);
+
+void VThread_WatchThread(VThreadID tid, Bool watched);
+void VThread_WatchDog(void);   // who let the ...
+void VThread_WatchDogPoll(void *clientData);
+
+void VThread_SetExitHook(void (*hook)(int loopCount));
+
+#ifdef _WIN32
+HANDLE VThread_GetHostThreadHandle(VThreadID tid);
+DWORD VThread_GetHostThreadID(VThreadID tid);
+#else
+int VThread_GetHostThreadPID(VThreadID tid);
+void VThread_SetIsInSignal(VThreadID tid, Bool isInSignal);
+#endif
+
+#endif // }
+
+#ifdef VTHREAD_RESOURCE_ACCOUNTING
+void VThread_DumpThreadRUsage(void);
+#else
+#define VThread_DumpThreadRUsage()
+#endif
+
+
+#endif // ifndef _VTHREAD_H_
diff --git a/open-vm-tools/lib/include/vthreadBase.h b/open-vm-tools/lib/include/vthreadBase.h
new file mode 100644 (file)
index 0000000..0cb9c7d
--- /dev/null
@@ -0,0 +1,93 @@
+/*********************************************************
+ * Copyright (C) 2006 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
+ * by the Free Software Foundation version 2.1 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the Lesser GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
+ *
+ *********************************************************/
+
+/*
+ * vthreadBase.h --
+ *
+ *     Subset of vthread defines that are used by libs that need to make
+ *      vthread calls but don't actually do any vthreading. These libs
+ *      can be linked against lib/nothread and will function correctly.
+ */
+
+#ifndef VTHREAD_BASE_H
+#define VTHREAD_BASE_H
+
+#define INCLUDE_ALLOW_USERLEVEL
+#define INCLUDE_ALLOW_VMMEXT
+#define INCLUDE_ALLOW_VMCORE
+#include "includeCheck.h"
+
+#if !defined VMM && !defined WIN32
+#define VTHREAD_USE_PTHREAD 1
+#endif
+
+
+/*
+ * Types
+ */
+
+typedef unsigned VThreadID;
+
+
+/*
+ * Constants
+ *
+ * VThread ID's are allocated this way:
+ *    0 -- VMX main thread
+ *    1 -- MKS
+ *    2 -- UI
+ *    3 -- other (main thread in simple apps)
+ *    4..3+VTHREAD_MAX_VCPUS -- VMX VCPU threads
+ *    4+VTHREAD_MAX_VCPUS.. -- additional dynamic threads
+ */
+
+#define VTHREAD_MAX_THREADS    96
+#define VTHREAD_MAX_VCPUS      32
+
+#define VTHREAD_INVALID_ID     (~0u)
+
+#define VTHREAD_VMX_ID         0
+#define VTHREAD_MKS_ID         1
+#define VTHREAD_UI_ID          2
+#define VTHREAD_OTHER_ID       3
+#define VTHREAD_VCPU0_ID       4
+#define VTHREAD_ALLOCSTART_ID  (VTHREAD_VCPU0_ID + VTHREAD_MAX_VCPUS)
+
+
+const char *VThread_CurName(void);
+
+#ifndef VMM
+VThreadID VThread_CurID(void);
+void VThread_Init(VThreadID tid, const char *name);
+VThreadID VThread_InitThread(VThreadID tid, const char *name);
+void NORETURN VThread_ExitThread(Bool clean);
+
+#ifdef _WIN32
+static INLINE Bool
+VThread_IsInSignal(void)
+{
+   /* Win32 does not worry about async-signal-safety. */
+   return FALSE;
+}
+#else
+Bool VThread_IsInSignal(void);
+#endif
+#endif
+
+
+#endif // VTHREAD_BASE_H
diff --git a/open-vm-tools/lib/lock/Makefile.am b/open-vm-tools/lib/lock/Makefile.am
new file mode 100644 (file)
index 0000000..fd232dc
--- /dev/null
@@ -0,0 +1,32 @@
+################################################################################
+### Copyright 2009 VMware, Inc.  All rights reserved.
+###
+### This program is free software; you can redistribute it and/or modify
+### it under the terms of version 2 of the GNU General Public License as
+### published by the Free Software Foundation.
+###
+### This program is distributed in the hope that it will be useful,
+### but WITHOUT ANY WARRANTY; without even the implied warranty of
+### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+### GNU General Public License for more details.
+###
+### You should have received a copy of the GNU General Public License
+### along with this program; if not, write to the Free Software
+### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+################################################################################
+
+noinst_LTLIBRARIES = libLock.la
+
+libLock_la_SOURCES =
+libLock_la_SOURCES += ul.c
+libLock_la_SOURCES += ulCreate.c
+libLock_la_SOURCES += ulDestroy.c
+libLock_la_SOURCES += ulAcquire.c
+libLock_la_SOURCES += ulRelease.c
+libLock_la_SOURCES += ulTryAcquire.c
+libLock_la_SOURCES += ulIsLocked.c
+libLock_la_SOURCES += ulSingleton.c
+libLock_la_SOURCES += ulRWPosix.c
+
+AM_CFLAGS = @LIB_LOCK_CPPFLAGS@
+
diff --git a/open-vm-tools/lib/lock/ul.c b/open-vm-tools/lib/lock/ul.c
new file mode 100644 (file)
index 0000000..22755c7
--- /dev/null
@@ -0,0 +1,122 @@
+/*********************************************************
+ * Copyright (C) 2009 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
+ * by the Free Software Foundation version 2.1 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the Lesser GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
+ *
+ *********************************************************/
+
+
+#include "vmware.h"
+#include "str.h"
+#include "util.h"
+#include "userlock.h"
+#include "ulInt.h"
+
+
+/*
+ * Return an invalid thread ID until lib/thread is initialized.
+ *
+ * XXX
+ *
+ * VThread_CurID cannot be called before VThread_Init is called; doing so
+ * causes assertion failures in some programs. This will go away when
+ * lib/nothread goes away - we'll assign "dense", rationalized VMware
+ * thread IDs without the distinction of lib/thread and lib/nothread.
+ */
+
+static VThreadID
+MXUserDummyCurID(void)
+{
+   return VTHREAD_INVALID_ID;
+}
+
+VThreadID (*MXUserThreadCurID)(void) = MXUserDummyCurID;
+
+void
+MXUserIDHack(void)
+{
+   MXUserThreadCurID = VThread_CurID;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * MXUserDumpAndPanic
+ *
+ *      Dump a lock, print a message and die
+ *
+ * Results:
+ *      A panic.
+ *
+ * Side effects:
+ *      Manifold.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+MXUserDumpAndPanic(MXRecLock *lock,   // IN:
+                   const char *fmt,   // IN:
+                   ...)               // IN:
+{
+   char *msg;
+   va_list ap;
+
+   Warning("%s: Lock @ %p\n",    __FUNCTION__, lock);
+   Warning("%s: signature %X\n", __FUNCTION__, lock->lockHeader.lockSignature);
+   Warning("%s: count %u\n",     __FUNCTION__, lock->lockHeader.lockCount);
+   Warning("%s: name %s\n",      __FUNCTION__, lock->lockHeader.lockName);
+   Warning("%s: caller %p\n",    __FUNCTION__, lock->lockHeader.lockCaller);
+   Warning("%s: rank %d\n",      __FUNCTION__, lock->lockHeader.lockRank);
+
+   Warning("%s: VThreadID %d\n", __FUNCTION__,
+           (int) lock->lockHeader.lockVThreadID);
+
+   va_start(ap, fmt);
+   msg = Str_SafeVasprintf(NULL, fmt, ap);
+   va_end(ap);
+
+   Panic(msg);
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * MXUserIsAllUnlocked --
+ *
+ *      Is the lock currently completely unlocked?
+ *
+ * Results:
+ *      The lock is acquired.
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+Bool
+MXUserIsAllUnlocked(const MXUserRWLock *lock)  // IN:
+{
+   uint32 i;
+
+   for (i = 0; i < VTHREAD_MAX_THREADS; i++) {
+      if (lock->lockTaken[i] != RW_UNLOCKED) {
+         return FALSE;
+      }
+   }
+
+   return TRUE;
+}
diff --git a/open-vm-tools/lib/lock/ulAcquire.c b/open-vm-tools/lib/lock/ulAcquire.c
new file mode 100644 (file)
index 0000000..68fed43
--- /dev/null
@@ -0,0 +1,77 @@
+/*********************************************************
+ * Copyright (C) 2009 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
+ * by the Free Software Foundation version 2.1 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the Lesser GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
+ *
+ *********************************************************/
+
+
+#include "vmware.h"
+#include "userlock.h"
+#include "ulInt.h"
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * MXUser_AcquireExclLock --
+ *
+ *      An acquisition is made (lock is taken) on the specified exclusive lock.
+ *
+ * Results:
+ *      The lock is acquired (locked).
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+MXUser_AcquireExclLock(MXUserExclLock *lock) // IN/OUT:
+{
+   MXRecLockAcquire(&lock->basic, MXGetThreadID(), GetReturnAddress());
+
+   if (MXRecLockCount(&lock->basic) > 1) {
+      MXUserDumpAndPanic(&lock->basic,
+                         "%s: Acquire on an acquired exclusive lock",
+                         __FUNCTION__);
+   }
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * MXUser_AcquireRecLock --
+ *
+ *      An acquisition is made (lock is taken) on the specified recursive
+ *      lock.
+ *
+ *      Only the owner (thread) of a recursive lock may recurse on it.
+ *
+ * Results:
+ *      The lock is acquired (locked).
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+MXUser_AcquireRecLock(MXUserRecLock *lock)  // IN/OUT:
+{
+   MXRecLockAcquire(&lock->basic, MXGetThreadID(), GetReturnAddress());
+}
diff --git a/open-vm-tools/lib/lock/ulCreate.c b/open-vm-tools/lib/lock/ulCreate.c
new file mode 100644 (file)
index 0000000..820cb6c
--- /dev/null
@@ -0,0 +1,112 @@
+/*********************************************************
+ * Copyright (C) 2009 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
+ * by the Free Software Foundation version 2.1 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the Lesser GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
+ *
+ *********************************************************/
+
+
+#include "vmware.h"
+#include "str.h"
+#include "util.h"
+#include "userlock.h"
+#include "ulInt.h"
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * MXUser_CreateExclLock --
+ *
+ *      Create an exclusive lock.
+ *
+ * Results:
+ *      NULL  Creation failed
+ *      !NULL Creation succeeded
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+MXUserExclLock *
+MXUser_CreateExclLock(const char *userName,  // IN:
+                      MX_Rank rank)          // IN:
+{
+   char *properName;
+   MXUserExclLock *lock;
+
+   lock = Util_SafeCalloc(1, sizeof(*lock));
+
+   if (userName == NULL) {
+      properName = Str_SafeAsprintf(NULL, "X-%p", GetReturnAddress());
+   } else {
+      properName = Util_SafeStrdup(userName);
+   }
+
+   if (!MXRecLockInit(&lock->basic, properName, rank)) {
+      free(lock);
+      free(properName);
+      lock = NULL;
+   }
+
+   return lock;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * MXUser_CreateRecLock --
+ *
+ *      Create a recursive lock.
+ *
+ *      Only the owner (thread) of a recursive lock may recurse on it.
+ *
+ * Results:
+ *      NULL  Creation failed
+ *      !NULL Creation succeeded
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+MXUserRecLock *
+MXUser_CreateRecLock(const char *userName,  // IN:
+                     MX_Rank rank)          // IN:
+{
+   char *properName;
+   MXUserRecLock *lock;
+
+   lock = Util_SafeCalloc(1, sizeof(*lock));
+
+   if (userName == NULL) {
+      properName = Str_SafeAsprintf(NULL, "R-%p", GetReturnAddress());
+   } else {
+      properName = Util_SafeStrdup(userName);
+   }
+
+   if (MXRecLockInit(&lock->basic, properName, rank)) {
+      lock->vmmLock = NULL;
+   } else {
+      free(lock);
+      free(properName);
+      lock = NULL;
+   }
+
+   return lock;
+}
diff --git a/open-vm-tools/lib/lock/ulDestroy.c b/open-vm-tools/lib/lock/ulDestroy.c
new file mode 100644 (file)
index 0000000..73f5240
--- /dev/null
@@ -0,0 +1,84 @@
+/*********************************************************
+ * Copyright (C) 2009 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
+ * by the Free Software Foundation version 2.1 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the Lesser GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
+ *
+ *********************************************************/
+
+#include "vmware.h"
+#include "userlock.h"
+#include "ulInt.h"
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * MXUser_DestroyExclLock --
+ *
+ *      Destroy an exclusive lock.
+ *
+ * Results:
+ *      Lock is destroyed. Don't use the pointer again.
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+MXUser_DestroyExclLock(MXUserExclLock *lock)  // IN:
+{
+   if (lock != NULL) {
+      if (MXRecLockCount(&lock->basic) > 0) {
+         MXUserDumpAndPanic(&lock->basic,
+                            "%s: Destroy of an acquired exclusive lock",
+                            __FUNCTION__);
+      }
+
+      MXRecLockDestroy(&lock->basic);
+      free(lock);
+   }
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * MXUser_DestroyRecLock --
+ *
+ *      Destroy a recursive lock.
+ *
+ * Results:
+ *      Lock is destroyed. Don't use the pointer again.
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+MXUser_DestroyRecLock(MXUserRecLock *lock)  // IN:
+{
+   if (lock != NULL) {
+      if (MXRecLockCount(&lock->basic) > 0) {
+         MXUserDumpAndPanic(&lock->basic,
+                            "%s: Destroy of an acquired recursive lock",
+                            __FUNCTION__);
+      }
+
+      MXRecLockDestroy(&lock->basic);
+      free(lock);
+   }
+}
diff --git a/open-vm-tools/lib/lock/ulInt.h b/open-vm-tools/lib/lock/ulInt.h
new file mode 100644 (file)
index 0000000..876d0ab
--- /dev/null
@@ -0,0 +1,471 @@
+/*********************************************************
+ * Copyright (C) 2009 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
+ * by the Free Software Foundation version 2.1 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the Lesser GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
+ *
+ *********************************************************/
+
+#ifndef _ULINT_H_
+#define _ULINT_H_
+
+#if defined(_WIN32)
+#include <windows.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#if defined(_WIN32)
+typedef DWORD MXThreadID;
+#else
+#include <pthread.h>
+#include <errno.h>
+typedef pthread_t MXThreadID;
+#endif
+
+#include "vm_basic_types.h"
+#include "vthread.h"
+
+/* XXX hack until thread/nothread IDs are rationalized */
+void MXUserIDHack(void);
+EXTERN VThreadID (*MXUserThreadCurID)(void);
+
+/*
+ * MXUser lock header - all MXUser locks start with this
+ */
+
+#define USERLOCK_SIGNATURE 0x75677976 // 'LOCK' in memory
+
+typedef struct {
+   const char    *lockName;
+   uint32         lockSignature;
+   int            lockCount;   // May be Atomic someday (read-write locks?)
+   MXThreadID     lockOwner;   // Native thread ID
+   MX_Rank        lockRank;
+   VThreadID      lockVThreadID;
+
+   /*
+    * Statistics data
+    *
+    * The fancy statistics that we will keep on each lock will live here too,
+    * attached via a pointer.
+    */
+
+   const void    *lockCaller;  // return address of lock acquisition routine
+} MXUserHeader;
+
+/*
+ * A portable recursive lock.
+ *
+ * The MXUser simple and recursive locks are built on top of this.
+ */
+
+#define MXUSER_MAX_REC_DEPTH 16
+
+typedef struct {
+   MXUserHeader     lockHeader;
+
+#if defined(_WIN32)
+   CRITICAL_SECTION lockObject;
+#else
+   pthread_mutex_t  lockObject;
+#endif
+} MXRecLock;
+
+
+/*
+ * Environment specific implementations of portable recursive locks.
+ *
+ * A recursive lock is used throughput the MXUser locks because:
+ *     - it can be used recursively for recursive locks
+ *     - exclusive (non-recursive) locks catch the recursion and panic
+ *       rather than deadlock.
+ *
+ * There are 7 environment specific primitives:
+ *
+ * MXGetThreadID       (thread identification)
+ * MXRecLockIsOwner    (is lock owned by caller?)
+ * MXRecLockObjectInit (initialize)
+ * MXRecLockDestroy    (dispose after use)
+ * MXRecLockAcquire    (lock)
+ * MXRecLockTryAcquire (conditional lock)
+ * MXRecLockRelease    (unlock)
+ *
+ * Windows has a native recursive lock, the CRITICAL_SECTION. POSIXen,
+ * unfortunately, do not ensure access to such a facility. The recursive
+ * attribute of pthread_mutex_t is not implemented in all environments so
+ * we create a recursive implementation using an exclusive pthread_mutex_t
+ * and a few lines of code (most of which we need to do anyway).
+ */
+
+#if defined(_WIN32)
+static INLINE MXThreadID
+MXGetThreadID(void)
+{
+   return GetCurrentThreadId();
+}
+
+
+static INLINE Bool
+MXRecLockIsOwner(const MXRecLock *lock)  // IN:
+{
+   ASSERT(lock->lockHeader.lockSignature == USERLOCK_SIGNATURE);
+
+   return lock->lockHeader.lockOwner == MXGetThreadID();
+}
+
+
+static INLINE Bool
+MXRecLockObjectInit(CRITICAL_SECTION *lockObject)  // IN/OUT:
+{
+   /* http://msdn.microsoft.com/en-us/library/ms682530(VS.85).aspx */
+   /* magic number - allocate resources immediately; spin 0x400 times */
+   return InitializeCriticalSectionAndSpinCount(lockObject, 0x80000400) != 0;
+}
+
+
+static INLINE void
+MXRecLockDestroy(MXRecLock *lock)  // IN/OUT:
+{
+   ASSERT(lock->lockHeader.lockSignature == USERLOCK_SIGNATURE);
+
+   DeleteCriticalSection(&lock->lockObject);
+   free((void *) lock->lockHeader.lockName);
+}
+
+
+static INLINE void
+MXRecLockAcquire(MXRecLock *lock,        // IN/OUT:
+                 MXThreadID self,        // IN:
+                 const void *location)   // IN:
+{
+   ASSERT(lock->lockHeader.lockSignature == USERLOCK_SIGNATURE);
+
+   EnterCriticalSection(&lock->lockObject);
+
+   ASSERT((lock->lockHeader.lockCount >= 0) &&
+          (lock->lockHeader.lockCount < MXUSER_MAX_REC_DEPTH));
+
+   if (lock->lockHeader.lockCount == 0) {
+      ASSERT(lock->lockHeader.lockVThreadID == VTHREAD_INVALID_ID);
+      lock->lockHeader.lockOwner = self;
+      lock->lockHeader.lockCaller = location;
+      lock->lockHeader.lockVThreadID = (*MXUserThreadCurID)();
+
+   }
+
+   lock->lockHeader.lockCount++;
+}
+
+
+static INLINE Bool
+MXRecLockTryAcquire(MXRecLock *lock,        // IN/OUT:
+                    MXThreadID self,        // IN:
+                    const void *location)   // IN:
+{
+   Bool success;
+
+   ASSERT(lock->lockHeader.lockSignature == USERLOCK_SIGNATURE);
+
+   success = TryEnterCriticalSection(&lock->lockObject);
+
+   if (success) {
+      ASSERT((lock->lockHeader.lockCount >= 0) &&
+             (lock->lockHeader.lockCount < MXUSER_MAX_REC_DEPTH));
+
+      if (lock->lockHeader.lockCount == 0) {
+         ASSERT(lock->lockHeader.lockVThreadID == VTHREAD_INVALID_ID);
+         lock->lockHeader.lockOwner = self;
+         lock->lockHeader.lockCaller = location;
+         lock->lockHeader.lockVThreadID = (*MXUserThreadCurID)();
+      }
+
+      lock->lockHeader.lockCount++;
+   }
+
+   return success;
+}
+
+
+static INLINE void
+MXRecLockRelease(MXRecLock *lock)  // IN/OUT:
+{
+   ASSERT(lock->lockHeader.lockSignature == USERLOCK_SIGNATURE);
+
+   ASSERT((lock->lockHeader.lockCount > 0) &&
+          (lock->lockHeader.lockCount < MXUSER_MAX_REC_DEPTH));
+
+   lock->lockHeader.lockCount--;
+
+   if (lock->lockHeader.lockCount == 0) {
+      lock->lockHeader.lockCaller = NULL;
+      lock->lockHeader.lockVThreadID = VTHREAD_INVALID_ID;
+   }
+
+   LeaveCriticalSection(&lock->lockObject);
+}
+#else
+static INLINE MXThreadID
+MXGetThreadID(void)
+{
+   return pthread_self();
+}
+
+
+static INLINE Bool
+MXRecLockIsOwner(const MXRecLock *lock)  // IN:
+{
+   ASSERT(lock->lockHeader.lockSignature == USERLOCK_SIGNATURE);
+
+   return pthread_equal(lock->lockHeader.lockOwner, pthread_self());
+}
+
+
+static INLINE Bool
+MXRecLockObjectInit(pthread_mutex_t *lockObject)  // IN/OUT:
+{
+   return pthread_mutex_init(lockObject, NULL) == 0;
+}
+
+
+static INLINE void
+MXRecLockDestroy(MXRecLock *lock)  // IN/OUT:
+{
+   int err;
+
+   ASSERT(lock->lockHeader.lockSignature == USERLOCK_SIGNATURE);
+
+   err = pthread_mutex_destroy(&lock->lockObject);
+
+   if (vmx86_debug && (err != 0)) {
+      Panic("%s: pthread_mutex_destroy returned %d\n", __FUNCTION__, err);
+   }
+
+   free((void *) lock->lockHeader.lockName);
+}
+
+
+static INLINE void
+MXRecLockAcquire(MXRecLock *lock,  // IN/OUT:
+                 MXThreadID self,  // IN:
+                 void *location)   // IN:
+{
+   ASSERT(lock->lockHeader.lockSignature == USERLOCK_SIGNATURE);
+
+   if ((lock->lockHeader.lockCount != 0) &&
+        pthread_equal(lock->lockHeader.lockOwner, pthread_self())) {
+      ASSERT((lock->lockHeader.lockCount > 0) &&
+             (lock->lockHeader.lockCount < MXUSER_MAX_REC_DEPTH));
+
+      lock->lockHeader.lockCount++;
+   } else {
+      int err;
+
+      err = pthread_mutex_lock(&lock->lockObject);
+
+      if (vmx86_debug && (err != 0)) {
+         Panic("%s: pthread_mutex_lock returned %d\n", __FUNCTION__, err);
+      }
+
+      ASSERT(lock->lockHeader.lockCount == 0);
+      ASSERT(lock->lockHeader.lockVThreadID == VTHREAD_INVALID_ID);
+
+      lock->lockHeader.lockOwner = self;
+      lock->lockHeader.lockCaller = location;
+      lock->lockHeader.lockCount = 1;
+      lock->lockHeader.lockVThreadID = (*MXUserThreadCurID)();
+   }
+}
+
+
+static INLINE Bool
+MXRecLockTryAcquire(MXRecLock *lock,  // IN/OUT:
+                    MXThreadID self,  // IN:
+                    void *location)   // IN:
+{
+   int err;
+   Bool acquired;
+
+   ASSERT(lock->lockHeader.lockSignature == USERLOCK_SIGNATURE);
+
+   err = pthread_mutex_trylock(&lock->lockObject);
+
+   if (err == 0) {
+      ASSERT((lock->lockHeader.lockCount >= 0) &&
+             (lock->lockHeader.lockCount < MXUSER_MAX_REC_DEPTH));
+
+      if (lock->lockHeader.lockCount == 0) {
+         ASSERT(lock->lockHeader.lockVThreadID == VTHREAD_INVALID_ID);
+         lock->lockHeader.lockOwner = self;
+         lock->lockHeader.lockCaller = location;
+         lock->lockHeader.lockVThreadID = (*MXUserThreadCurID)();
+      }
+
+      lock->lockHeader.lockCount++;
+
+      acquired = TRUE;
+   } else {
+      if (vmx86_debug && (err != EBUSY)) {
+         Panic("%s: pthread_mutex_trylock returned %d\n", __FUNCTION__, err);
+      }
+
+      acquired = FALSE;
+   }
+
+   return acquired;
+}
+
+
+static INLINE void
+MXRecLockRelease(MXRecLock *lock)  // IN/OUT:
+{
+   ASSERT(lock->lockHeader.lockSignature == USERLOCK_SIGNATURE);
+
+   ASSERT((lock->lockHeader.lockCount > 0) &&
+          (lock->lockHeader.lockCount < MXUSER_MAX_REC_DEPTH));
+
+   lock->lockHeader.lockCount--;
+
+   if (lock->lockHeader.lockCount == 0) {
+      int err;
+
+      lock->lockHeader.lockCaller = NULL;
+      lock->lockHeader.lockVThreadID = VTHREAD_INVALID_ID;
+
+      err = pthread_mutex_unlock(&lock->lockObject);
+
+      if (vmx86_debug && (err != 0)) {
+         Panic("%s: pthread_mutex_unlock returned %d\n", __FUNCTION__, err);
+      }
+   }
+}
+#endif
+
+
+static INLINE void
+MXRecLockInitHeader(MXRecLock *lock,       // IN/OUT:
+                    const char *userName,  // IN:
+                    MX_Rank rank)          // IN:
+{
+   lock->lockHeader.lockName = userName;
+   lock->lockHeader.lockSignature = USERLOCK_SIGNATURE;
+   lock->lockHeader.lockCount = 0;
+   lock->lockHeader.lockRank = rank;
+   lock->lockHeader.lockVThreadID = VTHREAD_INVALID_ID;
+   lock->lockHeader.lockCaller = NULL;
+}
+
+
+/*
+ * Initialization of portable recursive lock.
+ */
+
+static INLINE Bool
+MXRecLockInit(MXRecLock *lock,       // IN/OUT:
+              const char *userName,  // IN:
+              MX_Rank rank)          // IN:
+{
+   ASSERT(rank == RANK_UNRANKED);  // NOT FOR LONG
+   ASSERT(userName != NULL);
+
+   if (!MXRecLockObjectInit(&lock->lockObject)) {
+      return FALSE;
+   }
+
+   MXRecLockInitHeader(lock, userName, rank);
+
+   return TRUE;
+}
+
+
+static INLINE uint32
+MXRecLockCount(const MXRecLock *lock)  // IN:
+{
+   ASSERT(lock->lockHeader.lockSignature == USERLOCK_SIGNATURE);
+
+   return lock->lockHeader.lockCount;
+}
+
+
+static INLINE const char *
+MXRecLockName(const MXRecLock *lock)  // IN:
+{
+   ASSERT(lock->lockHeader.lockSignature == USERLOCK_SIGNATURE);
+
+   return lock->lockHeader.lockName;
+}
+
+
+static INLINE uint32
+MXRecLockSignature(const MXRecLock *lock)  // IN:
+{
+   return lock->lockHeader.lockSignature;
+}
+
+/*
+ * The internal lock types
+ */
+
+struct MXUserExclLock
+{
+   MXRecLock basic;
+};
+
+struct MXUserRecLock
+{
+   MXRecLock  basic;
+
+   /*
+    * This is the MX recursive lock override pointer. This pointer is NULL
+    * for standard MXUser recursive locks. It will be not NULL when a
+    * special "bind an MXUser recursive lock to an MX recursive lock"
+    * function is called. The binding function will come along in the near
+    * future. This will make things like Poll able to user MXUser locks.
+    *
+    *  NULL   use MXRecLock within this structure
+    * !NULL   use pointed to MX recursive lock
+    */
+
+   void      *vmmLock;
+};
+
+struct MXUserRWLock
+{
+   MXRecLock         lockRecursive;  // Used as a header or maybe for real
+
+   uint8             lockTaken[VTHREAD_MAX_THREADS];
+
+#if defined(_WIN32)
+   SRWLOCK           lockReadWrite;
+#else
+#if defined(PTHREAD_RWLOCK_INITIALIZER)
+   pthread_rwlock_t  lockObject;
+#endif
+#endif
+};
+
+/*
+ * Internal functions
+ */
+
+#define RW_UNLOCKED          0
+#define RW_LOCKED_FOR_READ   1
+#define RW_LOCKED_FOR_WRITE  2
+
+Bool MXUserIsAllUnlocked(const MXUserRWLock *lock);
+
+void MXUserDumpAndPanic(MXRecLock *lock,
+                        const char *fmt,
+                        ...);
+#endif
diff --git a/open-vm-tools/lib/lock/ulIsLocked.c b/open-vm-tools/lib/lock/ulIsLocked.c
new file mode 100644 (file)
index 0000000..8626199
--- /dev/null
@@ -0,0 +1,70 @@
+/*********************************************************
+ * Copyright (C) 2009 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
+ * by the Free Software Foundation version 2.1 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the Lesser GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
+ *
+ *********************************************************/
+
+#include "vmware.h"
+#include "userlock.h"
+#include "ulInt.h"
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * MXUser_IsLockedByCurThreadExclLock --
+ *
+ *      Is an exclusive lock held by the calling thread?
+ *
+ * Results:
+ *      TRUE    Yes
+ *      FALSE   No
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+Bool
+MXUser_IsLockedByCurThreadExclLock(const MXUserExclLock *lock)  // IN:
+{
+   return MXRecLockIsOwner(&lock->basic);
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * MXUser_IsLockedByCurThreadRecLock --
+ *
+ *      Is a recursive lock held by the calling thread?
+ *
+ * Results:
+ *      TRUE    Yes
+ *      FALSE   No
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+Bool
+MXUser_IsLockedByCurThreadRecLock(const MXUserRecLock *lock)  // IN:
+{
+   return MXRecLockIsOwner(&lock->basic);
+}
+
diff --git a/open-vm-tools/lib/lock/ulRWPosix.c b/open-vm-tools/lib/lock/ulRWPosix.c
new file mode 100644 (file)
index 0000000..f22a192
--- /dev/null
@@ -0,0 +1,287 @@
+/*********************************************************
+ * Copyright (C) 2009 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
+ * by the Free Software Foundation version 2.1 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the Lesser GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
+ *
+ *********************************************************/
+
+#include <errno.h>
+
+#include "vmware.h"
+#include "str.h"
+#include "util.h"
+#include "userlock.h"
+#include "ulInt.h"
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * MXUser_CreateRWLock --
+ *
+ *      Create a read-write lock.
+ *
+ * Results:
+ *      A pointer to a read-write lock.
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+MXUserRWLock *
+MXUser_CreateRWLock(const char *userName,  // IN:
+                    MX_Rank rank)          // IN:
+{
+   char *properName;
+   MXUserRWLock *lock;
+
+   ASSERT(rank == RANK_UNRANKED);  // NOT FOR LONG
+
+   lock = Util_SafeCalloc(1, sizeof(*lock));
+
+   if (userName == NULL) {
+#if defined(PTHREAD_RWLOCK_INITIALIZER)
+      properName = Str_SafeAsprintf(NULL, "RW-%p", GetReturnAddress());
+#else
+      /* emulated */
+      properName = Str_SafeAsprintf(NULL, "RWemul-%p", GetReturnAddress());
+#endif
+   } else {
+      properName = Util_SafeStrdup(userName);
+   }
+
+#if defined(PTHREAD_RWLOCK_INITIALIZER)
+   if (pthread_rwlock_init(&lock->lockObject, NULL) != 0) {
+      free((void *) properName);
+      free(lock);
+      lock = NULL;
+   }
+#endif
+
+   /* Establish standard header. This may get used for real too. */
+   if (!MXRecLockInit(&lock->lockRecursive, properName, rank)) {
+      free((void *) properName);
+      free(lock);
+      lock = NULL;
+   }
+
+   return lock;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * MXUser_AcquireForRead --
+ *
+ *      Acquire a read-write lock for read-shared access.
+ *
+ * Results:
+ *      The lock is acquired.
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+MXUser_AcquireForRead(MXUserRWLock *lock)  // IN/OUT:
+{
+#if defined(PTHREAD_RWLOCK_INITIALIZER)
+   int err;
+#endif
+
+   VThreadID self = VThread_CurID();
+
+   ASSERT(MXRecLockSignature(&lock->lockRecursive) == USERLOCK_SIGNATURE);
+
+#if defined(PTHREAD_RWLOCK_INITIALIZER)
+   err = pthread_rwlock_rdlock(&lock->lockObject);
+
+   if (err == 0) {
+      if (lock->lockTaken[self] == RW_LOCKED_FOR_READ) {
+         MXUserDumpAndPanic(&lock->lockRecursive,
+                            "%s: AcquireForRead after AcquireForRead",
+                            __FUNCTION__);
+      }
+   } else {
+      MXUserDumpAndPanic(&lock->lockRecursive, "%s: %s",
+                         (err == EDEADLK) ? "Deadlock detected (%d)" :
+                                            "Internal error (%d)",
+                         __FUNCTION__, err);
+   }
+#else
+   MXRecLockAcquire(&lock->lockRecursive, MXGetThreadID(), GetReturnAddress());
+
+   if (lock->lockTaken[self] != RW_UNLOCKED) {
+      if (lock->lockTaken[self] == RW_LOCKED_FOR_READ) {
+         MXUserDumpAndPanic(&lock->lockRecursive,
+                            "%s: AcquireForRead after AcquireForRead"
+                            __FUNCTION__, self);
+      } else {
+         MXUserDumpAndPanic(&lock->lockRecursive,
+                            "%s: AcquireForRead after AcquireForWrite"
+                            __FUNCTION__, self);
+      }
+   }
+
+   ASSERT(MXUserIsAllUnlocked(lock));
+#endif
+
+   lock->lockTaken[self] = RW_LOCKED_FOR_READ;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * MXUser_AcquireForWrite --
+ *
+ *      Acquire a read-write lock for write-exclusive access.
+ *
+ * Results:
+ *      The lock is acquired.
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+MXUser_AcquireForWrite(MXUserRWLock *lock)  // IN/OUT:
+{
+#if defined(PTHREAD_RWLOCK_INITIALIZER)
+   int err;
+#endif
+
+   VThreadID self = VThread_CurID();
+
+   ASSERT(MXRecLockSignature(&lock->lockRecursive) == USERLOCK_SIGNATURE);
+
+#if defined(PTHREAD_RWLOCK_INITIALIZER)
+   err = pthread_rwlock_wrlock(&lock->lockObject);
+
+   if (err != 0) {
+      MXUserDumpAndPanic(&lock->lockRecursive, "%s: %s",
+                         (err == EDEADLK) ? "Deadlock detected (%d)" :
+                                            "Internal error (%d)",
+                         __FUNCTION__, err);
+   }
+#else
+   MXRecLockAcquire(&lock->lockRecursive, MXGetThreadID(), GetReturnAddress());
+
+   if (lock->lockTaken[self] != RW_UNLOCKED) {
+      if (lock->lockTaken[self] == RW_LOCKED_FOR_READ) {
+         MXUserDumpAndPanic(&lock->lockRecursive,
+                            "%s: AcquireForRead after AcquireForWrite"
+                            __FUNCTION__);
+      } else {
+         MXUserDumpAndPanic(&lock->lockRecursive,
+                            "%s: AcquireForWrite after AcquireForWrite"
+                            __FUNCTION__);
+      }
+   }
+#endif
+
+   ASSERT(MXUserIsAllUnlocked(lock));
+
+   lock->lockTaken[self] = RW_LOCKED_FOR_WRITE;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * MXUser_ReleaseRWLock --
+ *
+ *      A read-write lock is released (unlocked).
+ *
+ * Results:
+ *      The lock is released (unlocked).
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+MXUser_ReleaseRWLock(MXUserRWLock *lock)  // IN/OUT:
+{
+   VThreadID self = VThread_CurID();
+   uint8 myState = lock->lockTaken[self];
+
+   ASSERT(MXRecLockSignature(&lock->lockRecursive) == USERLOCK_SIGNATURE);
+
+   if (myState == RW_UNLOCKED) {
+      MXUserDumpAndPanic(&lock->lockRecursive,
+                         "%s: Release of read-lock not by owner (%d)",
+                         __FUNCTION__, self);
+   }
+
+   lock->lockTaken[self] = RW_UNLOCKED;
+
+#if defined(PTHREAD_RWLOCK_INITIALIZER)
+   if (vmx86_debug && (myState == RW_LOCKED_FOR_WRITE)) {
+      ASSERT(MXUserIsAllUnlocked(lock));
+   }
+
+   pthread_rwlock_unlock(&lock->lockObject);
+#else
+   ASSERT(MXUserIsAllUnlocked(lock));
+   MXRecLockRelease(&lock->lockRecursive);
+#endif
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * MXUser_DestroyRWLock --
+ *
+ *      Destroy a read-write lock.
+ *
+ * Results:
+ *      The lock is destroyed. Don't try to use the pointer again.
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+MXUser_DestroyRWLock(MXUserRWLock *lock)  // IN:
+{
+   if (lock != NULL) {
+      ASSERT(MXRecLockSignature(&lock->lockRecursive) == USERLOCK_SIGNATURE);
+
+      if (!MXUserIsAllUnlocked(lock)) {
+         MXUserDumpAndPanic(&lock->lockRecursive,
+                            "%s: Destroy on read-lock while still acquired",
+                            __FUNCTION__);
+      }
+
+#if defined(PTHREAD_RWLOCK_INITIALIZER)
+      pthread_rwlock_destroy(&lock->lockObject);
+#endif
+
+      MXRecLockDestroy(&lock->lockRecursive);
+      free(lock);
+   }
+}
diff --git a/open-vm-tools/lib/lock/ulRelease.c b/open-vm-tools/lib/lock/ulRelease.c
new file mode 100644 (file)
index 0000000..dc2d724
--- /dev/null
@@ -0,0 +1,101 @@
+/*********************************************************
+ * Copyright (C) 2009 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
+ * by the Free Software Foundation version 2.1 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the Lesser GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
+ *
+ *********************************************************/
+
+#include "vmware.h"
+#include "userlock.h"
+#include "ulInt.h"
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * MXUserReleaseExclLock --
+ *
+ *      Release (unlock) a lock.
+ *
+ * Results:
+ *      The lock is released.
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static INLINE void
+MXUserReleaseExclLock(MXRecLock *lock,  // IN/OUT:
+                      char *type)       // IN:
+{
+   if (!MXRecLockIsOwner(lock)) {
+      if (MXRecLockCount(lock) == 0) {
+         MXUserDumpAndPanic(lock, "%s: Release of an unacquired %s lock",
+                            __FUNCTION__, type);
+      } else {
+         MXUserDumpAndPanic(lock, "%s: Release of owned %s lock",
+                            __FUNCTION__, type);
+      }
+   }
+
+   MXRecLockRelease(lock);
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * MXUser_ReleaseExclLock --
+ *
+ *      Release (unlock) an exclusive lock.
+ *
+ * Results:
+ *      The lock is released.
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+MXUser_ReleaseExclLock(MXUserExclLock *lock)  // IN/OUT:
+{
+   MXUserReleaseExclLock(&lock->basic, "exclusive");
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * MXUser_ReleaseRecLock --
+ *
+ *      Release (unlock) a recursive lock.
+ *
+ * Results:
+ *      The lock is released.
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+MXUser_ReleaseRecLock(MXUserRecLock *lock)  // IN/OUT:
+{
+   MXUserReleaseExclLock(&lock->basic, "recursive");
+}
diff --git a/open-vm-tools/lib/lock/ulSingleton.c b/open-vm-tools/lib/lock/ulSingleton.c
new file mode 100644 (file)
index 0000000..54c7f0e
--- /dev/null
@@ -0,0 +1,112 @@
+/*********************************************************
+ * Copyright (C) 2009 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
+ * by the Free Software Foundation version 2.1 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the Lesser GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
+ *
+ *********************************************************/
+
+#include "vmware.h"
+#include "userlock.h"
+#include "ulInt.h"
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * MXUser_CreateSingletonExclLock --
+ *
+ *      Ensures that the specified backing object (Atomic_Ptr) contains a
+ *      exclusive lock. This is useful for modules that need to protect
+ *      something with a lock but don't have an existing Init() entry point
+ *      where a lock can be created.
+ *
+ * Results:
+ *      A pointer to the requested lock.
+ *
+ * Side effects:
+ *      Generally the lock's resources are intentionally leaked (by design).
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+MXUserExclLock *
+MXUser_CreateSingletonExclLock(Atomic_Ptr *lockStorage,  // IN/OUT:
+                               const char *name,         // IN:
+                               MX_Rank rank)             // IN:
+{
+   MXUserExclLock *lock = (MXUserExclLock *) Atomic_ReadPtr(lockStorage);
+
+   if (UNLIKELY(lock == NULL)) {
+      MXUserExclLock *before;
+
+      lock = MXUser_CreateExclLock(name, rank);
+
+      before = (MXUserExclLock *) Atomic_ReadIfEqualWritePtr(lockStorage, NULL,
+                                                           (void *) lock);
+
+      if (before) {
+         MXUser_DestroyExclLock(lock);
+
+         lock = before;
+      }
+   }
+
+   return lock;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * MXUser_CreateSingletonRecLock --
+ *
+ *      Ensures that the specified backing object (Atomic_Ptr) contains a
+ *      recursive lock. This is useful for modules that need to protect
+ *      something with a lock but don't have an existing Init() entry point
+ *      where a lock can be created.
+ *
+ * Results:
+ *      A pointer to the requested lock.
+ *
+ * Side effects:
+ *      Generally the lock's resources are intentionally leaked (by design).
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+MXUserRecLock *
+MXUser_CreateSingletonRecLock(Atomic_Ptr *lockStorage,  // IN/OUT:
+                              const char *name,         // IN:
+                              MX_Rank rank)             // IN:
+{
+   MXUserRecLock *lock = (MXUserRecLock *) Atomic_ReadPtr(lockStorage);
+
+   if (UNLIKELY(lock == NULL)) {
+      MXUserRecLock *before;
+
+      lock = MXUser_CreateRecLock(name, rank);
+
+      before = (MXUserRecLock *) Atomic_ReadIfEqualWritePtr(lockStorage, NULL,
+                                                            (void *) lock);
+
+      if (before) {
+         MXUser_DestroyRecLock(lock);
+
+         lock = before;
+      }
+   }
+
+   return lock;
+}
+
diff --git a/open-vm-tools/lib/lock/ulTryAcquire.c b/open-vm-tools/lib/lock/ulTryAcquire.c
new file mode 100644 (file)
index 0000000..e4dd8a2
--- /dev/null
@@ -0,0 +1,84 @@
+/*********************************************************
+ * Copyright (C) 2009 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
+ * by the Free Software Foundation version 2.1 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the Lesser GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
+ *
+ *********************************************************/
+
+
+#include "vmware.h"
+#include "userlock.h"
+#include "ulInt.h"
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * MXUser_TryAcquireExclLock --
+ *
+ *      An attempt is made to conditionally acquire (lock) an exclusive lock.
+ *
+ * Results:
+ *      TRUE    Acquired (locked)
+ *      FALSE   Not acquired
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+Bool
+MXUser_TryAcquireExclLock(MXUserExclLock *lock)  // IN/OUT:
+{
+   Bool success;
+
+   success = MXRecLockTryAcquire(&lock->basic, MXGetThreadID(),
+                                 GetReturnAddress());
+
+   if (success && (MXRecLockCount(&lock->basic) > 1)) {
+      MXUserDumpAndPanic(&lock->basic,
+                         "%s: Acquire on an acquired exclusive lock",
+                         __FUNCTION__);
+   }
+
+   return success;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * MXUser_TryAcquireRecLock --
+ *
+ *      An attempt is made to conditionally acquire (lock) a recursive lock.
+ *
+ *      Only the owner (thread) of a recursive lock may recurse on it.
+ *
+ * Results:
+ *      TRUE    Acquired (locked)
+ *      FALSE   Not acquired
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+Bool
+MXUser_TryAcquireRecLock(MXUserRecLock *lock)  // IN/OUT:
+{
+   return MXRecLockTryAcquire(&lock->basic, MXGetThreadID(),
+                              GetReturnAddress());
+}
diff --git a/open-vm-tools/lib/nothread/Makefile.am b/open-vm-tools/lib/nothread/Makefile.am
new file mode 100644 (file)
index 0000000..bc630e3
--- /dev/null
@@ -0,0 +1,24 @@
+################################################################################
+### Copyright 2009 VMware, Inc.  All rights reserved.
+###
+### This program is free software; you can redistribute it and/or modify
+### it under the terms of version 2 of the GNU General Public License as
+### published by the Free Software Foundation.
+###
+### This program is distributed in the hope that it will be useful,
+### but WITHOUT ANY WARRANTY; without even the implied warranty of
+### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+### GNU General Public License for more details.
+###
+### You should have received a copy of the GNU General Public License
+### along with this program; if not, write to the Free Software
+### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+################################################################################
+
+noinst_LTLIBRARIES = libNothread.la
+
+libNothread_la_SOURCES =
+libNothread_la_SOURCES += vthreadUL.c
+
+AM_CFLAGS = @LIB_NOTHREAD_CPPFLAGS@
+
diff --git a/open-vm-tools/lib/nothread/vthreadUL.c b/open-vm-tools/lib/nothread/vthreadUL.c
new file mode 100644 (file)
index 0000000..1d53cca
--- /dev/null
@@ -0,0 +1,365 @@
+/*********************************************************
+ * Copyright (C) 2002 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
+ * by the Free Software Foundation version 2.1 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the Lesser GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
+ *
+ *********************************************************/
+
+/*
+ * vthreadUL.c --
+ *
+ *     Thread management without actually having threads
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#if defined(_WIN32)
+#include <windows.h>
+#elif defined(__APPLE__) || defined(__GLIBC__)
+#include <pthread.h>
+#endif
+
+#include "vmware.h"
+#include "vthreadBase.h"
+#include "str.h"
+
+
+/*
+ * Local data
+ *
+ * Initialize thread ID and name so VThread_Init() is optional.
+ */
+
+static VThreadID vthreadCurID = VTHREAD_OTHER_ID;
+static uintptr_t vthreadHostThreadID = 0;
+static Bool vthreadIsInSignal = FALSE;
+
+#if VTHREAD_OTHER_ID != 3
+#error "VTHREAD_OTHER_ID is not 3"
+#endif
+
+static char vthreadNames[VTHREAD_MAX_THREADS][32] = {
+   "",
+   "",
+   "",
+   "app"
+};
+
+/*
+ * Symbol that needs to be available for lib/lock.
+ */
+
+VThreadID vthreadMaxVCPUID = VTHREAD_VCPU0_ID;
+
+/*
+ * Local functions
+ */
+
+// nothing
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * VThreadHostThreadID --
+ *
+ *      Determine some sort of OS-specific unique threadID.
+ *
+ *      Nominally, lib/nothread is single-threaded; HostThreadID
+ *      would help us detect multithreaded violators.
+ *
+ * Results:
+ *      A per-thread unique uintptr_t.
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static uintptr_t
+VThreadHostThreadID(void)
+{
+#if defined(_WIN32)
+   return GetCurrentThreadId();
+#elif defined(__GLIBC__)
+   return pthread_self();
+#elif defined(__APPLE__)
+   return (uintptr_t)(void*)pthread_self();
+#else
+   return -1;
+#endif
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * VThread_Init --
+ *
+ *      Module and main thread initialization.
+ *
+ *      This should be called by the main thread early.
+ *
+ *      See VThread_InitThread.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      Set initial state.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+VThread_Init(VThreadID id,      // IN: this thread's ID
+             const char *name)  // IN: this thread's name
+{
+   if (id == VTHREAD_INVALID_ID) {
+      id = VTHREAD_OTHER_ID;
+   }
+   ASSERT(id >= 0 && id < VTHREAD_VCPU0_ID);
+
+   vthreadCurID = id;
+
+   if (vthreadHostThreadID == 0) {
+      vthreadHostThreadID = VThreadHostThreadID();
+   }
+
+   ASSERT(name != NULL);
+   ASSERT(vthreadNames[id][ARRAYSIZE(vthreadNames[id]) - 1] == '\0');
+   strncpy(vthreadNames[id], name, ARRAYSIZE(vthreadNames[id]) - 1);
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * VThread_InitThread --
+ *
+ *      Initialize a thread.
+ *
+ *      This should be called by threads started outside our control.
+ *      Threads started by VThread_CreateThread need to do nothing.
+ *
+ * Results:
+ *      The thread ID.
+ *
+ * Side effects:
+ *      Set initial state.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+VThreadID
+VThread_InitThread(VThreadID id,      // IN: this thread's ID
+                   const char *name)  // IN: this thread's name
+{
+   if (id == VTHREAD_INVALID_ID) {
+      /*
+       * XXX This emulates some old, broken expectations of callers
+       * of Thread_Init(VTHREAD_OTHER_ID) in third-party threads
+       * that can also link with either lib/thread or lib/nothread.
+       * The calls have become VThread_InitThread(VTHREAD_INVALID_ID),
+       * and should behave in the same broken way here and correctly
+       * in lib/thread.
+       */
+
+      id = VTHREAD_OTHER_ID;
+   } else {
+      ASSERT(id >= VTHREAD_ALLOCSTART_ID && id < VTHREAD_MAX_THREADS);
+   }
+
+   vthreadCurID = id;
+
+   if (vthreadHostThreadID == 0) {
+      vthreadHostThreadID = VThreadHostThreadID();
+   }
+
+   if (name == NULL) {
+      Str_Snprintf(vthreadNames[id], ARRAYSIZE(vthreadNames[id]),
+                  "vthread-%d", id);
+   } else {
+      ASSERT(vthreadNames[id][ARRAYSIZE(vthreadNames[id]) - 1] == '\0');
+      strncpy(vthreadNames[id], name, ARRAYSIZE(vthreadNames[id]) - 1);
+   }
+
+   return id;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * VThread_CurID --
+ *
+ *      Get the current thread ID.
+ *
+ * Results:
+ *      Thread ID.
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+VThreadID
+VThread_CurID(void)
+{
+   ASSERT(vthreadCurID < VTHREAD_MAX_THREADS);
+
+   return vthreadCurID;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * VThread_CurName --
+ *
+ *      Get the current thread name.
+ *
+ * Results:
+ *      The current thread name.
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+const char *
+VThread_CurName(void)
+{
+   uintptr_t hostTID = VThreadHostThreadID();
+
+   if (LIKELY(hostTID == vthreadHostThreadID)) {
+      return vthreadNames[vthreadCurID];
+   } else {
+      static char name[48];
+
+      /*
+       * There were multiple threads.  Do our best,
+       * but use a static buffer because clients shouldn't be
+       * using us anyway if they are multithreaded.
+       *
+       * XXX: in the future, we should wean people off
+       * lib/nothread by putting an ASSERT here!
+       */
+
+      snprintf(name, sizeof name, "%s-%"FMTPD"u",
+               vthreadNames[vthreadCurID], hostTID);
+      name[sizeof name - 1] = '\0';
+
+      return name;
+   }
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * VThread_ExitThread --
+ *
+ *      Exit.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      Bye bye.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+VThread_ExitThread(Bool clean)  // IN:
+{
+   /*
+    * On Linux, we can't possibly have threads, since we're not
+    * supposed to link with libpthread.
+    * So plain exit() will (and has to) do.
+    *
+    * On Windows, it's unclear what we should do here.
+    * There may or may not be threads, but this module doesn't know
+    * either way.  It depends on the caller's intent.
+    *
+    * The very first caller of this function was an old
+    * WS UI.  Since that was a process on Linux
+    * and a thread on Windows, we acted accordingly.
+    * It still seems to be a good idea.
+    *
+    * -- edward
+    */
+
+#if defined(_WIN32)
+   ExitThread(clean ? 0 : 1);
+#else
+   exit(clean ? 0 : 1);
+#endif
+
+   NOT_REACHED();
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VThread_SetIsInSignal --
+ *
+ *      Set the 'is in signal' state.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      Changes internal state.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+void
+VThread_SetIsInSignal(VThreadID tid,    // IN:
+                      Bool isInSignal)  // IN:
+{
+   vthreadIsInSignal = isInSignal;
+}
+
+
+#if !defined(_WIN32)
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VThread_IsInSignal --
+ *
+ *      Return the 'is in signal' state.
+ *
+ * Results:
+ *      Returns last value passed to VThread_SetIsInSignal.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+Bool
+VThread_IsInSignal(void)
+{
+   return vthreadIsInSignal;
+}
+#endif
index 25f31ddfc48c9c8417a4328953d5c3b95e408e97..d23776e782197437441b9141300346def9e729f3 100644 (file)
@@ -138,56 +138,6 @@ SyncMutex_Unlock(SyncMutex *that) // IN
 }
 
 
-/*
- *-----------------------------------------------------------------------------
- *
- * SyncMutex_CreateSingleton --
- *
- *      Creates and returns a mutex backed by the specified storage in a
- *      thread-safe manner. This is useful for modules that need to
- *      protect something with a lock but don't have an existing Init()
- *      entry point where a lock can be created.
- *
- * Results:
- *      A pointer to the mutex. Don't destroy it.
- *
- * Side effects:
- *      None.
- *
- *-----------------------------------------------------------------------------
- */
-
-SyncMutex *
-SyncMutex_CreateSingleton(Atomic_Ptr *lckStorage) // IN
-{
-   SyncMutex *before, *lck;
-
-   /* Check if we've created the lock already. */
-   lck = (SyncMutex *) Atomic_ReadPtr(lckStorage);
-
-   if (UNLIKELY(NULL == lck)) {
-      /* We haven't, create it. */
-      lck = (SyncMutex *) Util_SafeMalloc(sizeof *lck);
-      SyncMutex_Init(lck, NULL);
-
-      /*
-       * We have successfully created the lock, save it.
-       */
-
-      before = (SyncMutex *) Atomic_ReadIfEqualWritePtr(lckStorage, NULL, lck);
-
-      if (before) {
-         /* We raced and lost, but it's all cool. */
-         SyncMutex_Destroy(lck);
-         free(lck);
-         lck = before;
-      }
-   }
-
-   return lck;
-}
-
-
 /*
  *-----------------------------------------------------------------------------
  *
index 990f5e05b5fa66ba805e1fff1faa71538f6bfac9..9c8049b79b08b9e6d6c66f4b84bf1a58108d7eed 100644 (file)
@@ -263,6 +263,13 @@ Unity_Init(GuestApp_Dict *conf,                                    // IN
            int *blockedWnd,                                        // IN
            DesktopSwitchCallbackManager *desktopSwitchCallbackMgr) // IN
 {
+   /*
+    * If no preferred color is in the config file then use a light gray tone,
+    * the value is stored as xBGR.
+    */
+   int desktopColor =  /* red */ 0xdc |
+                       /* green */ 0xdc << 8 |
+                       /* blue */ 0xdc << 16;
    Debug("Unity_Init\n");
 
    /*
@@ -312,6 +319,8 @@ Unity_Init(GuestApp_Dict *conf,                                    // IN
    unity.forceEnable = GuestApp_GetDictEntryBool(conf, "unity.forceEnable");
    unity.isEnabled = FALSE;
 
+   GuestApp_GetDictEntryInt(conf, "unity.desktop.backgroundColor", &desktopColor);
+   UnityPlatformSetConfigDesktopColor(unity.up, desktopColor);
    unity.virtDesktopArray.desktopCount = 0;
 }
 
index a283a6179462be8a561e028f913d2a3f7734f4bb..ad1751dd0e02549b36efd30110924d32e8f1df93 100644 (file)
@@ -131,6 +131,8 @@ void UnityPlatformSetActiveDnDDetWnd(UnityPlatform *up, UnityDnD *detWnd);
 
 void UnityPlatformDoUpdate(UnityPlatform *up, Bool incremental);
 
+void UnityPlatformSetConfigDesktopColor(UnityPlatform *up, int desktopColor);
+
 /* Functions implemented in unity.c for use by the platform-specific code. */
 void UnityGetUpdateCommon(int flags, DynBuf *buf);
 Bool UnityUpdateChannelInit(UnityUpdateChannel *updateChannel);
index 338f144e3bb7b3eb7f26ce71af988dbc92dd9672..9c5cf012baaf8f59e738cfcd57da6ad33e5da64f 100644 (file)
@@ -3010,6 +3010,29 @@ UnityPlatformUnstickWindow(UnityPlatform *up,      // IN
 }
 
 
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * UnityPlatformSetConfigDesktopColor --
+ *
+ *      Set the preferred desktop background color for use when in Unity Mode.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+UnityPlatformSetConfigDesktopColor(UnityPlatform *up, int desktopColor)
+{
+   ASSERT(up);
+}
+
+
 /*
  ******************************************************************************
  * Begin file-scope functions.
index 657973d7bcdd0b44ab7a136f4e6bf27b7a7baaa7..85cdb3b4052e4185d68e31f8a3928e3146c0ff77 100644 (file)
@@ -53,7 +53,7 @@
 #include "vm_version.h"
 #include "random.h"
 #include "hostinfo.h"
-#include "syncMutex.h"
+#include "userlock.h"
 #include "escape.h"
 #include "unicodeOperations.h"
 #include "err.h"
@@ -556,13 +556,16 @@ Util_GetSafeTmpDir(Bool useConf) // IN
    char *baseTmpDir = NULL;
    char *userName = NULL;
    uid_t userId;
-   SyncMutex *lck;
+   MXUserExclLock *lck;
 
    userId = geteuid();
 
    /* Get and take lock for our safe dir. */
-   lck = SyncMutex_CreateSingleton(&lckStorage);
-   SyncMutex_Lock(lck);
+   lck = MXUser_CreateSingletonExclLock(&lckStorage, __FUNCTION__,
+                                        RANK_UNRANKED);
+   ASSERT_NOT_IMPLEMENTED(lck != NULL);
+
+   MXUser_AcquireExclLock(lck);
 
    /*
     * Check if we've created a temporary dir already and if it is
@@ -636,7 +639,7 @@ Util_GetSafeTmpDir(Bool useConf) // IN
    }
 
   exit:
-   SyncMutex_Unlock(lck);
+   MXUser_ReleaseExclLock(lck);
    free(baseTmpDir);
    free(userName);
 
index 9a4ea93f90616951732a4ed60476f86a74a555c5..0a9fc7279bdbd7af6d8a15903208850cc661c0d6 100644 (file)
@@ -29,7 +29,6 @@ libvmtools_la_LIBADD += ../lib/guestInfo/libGuestInfo.la
 libvmtools_la_LIBADD += ../lib/guestRpc/libGuestRpc.la
 libvmtools_la_LIBADD += ../lib/hgfs/libHgfs.la
 libvmtools_la_LIBADD += ../lib/message/libMessage.la
-libvmtools_la_LIBADD += ../lib/misc/libMisc.la
 libvmtools_la_LIBADD += ../lib/netUtil/libNetUtil.la
 libvmtools_la_LIBADD += ../lib/panic/libPanic.la
 libvmtools_la_LIBADD += ../lib/procMgr/libProcMgr.la
@@ -46,6 +45,9 @@ libvmtools_la_LIBADD += ../lib/user/libUser.la
 libvmtools_la_LIBADD += ../lib/vmCheck/libVmCheck.la
 libvmtools_la_LIBADD += ../lib/vmSignal/libVmSignal.la
 libvmtools_la_LIBADD += ../lib/wiper/libWiper.la
+libvmtools_la_LIBADD += ../lib/lock/libLock.la
+libvmtools_la_LIBADD += ../lib/nothread/libNothread.la
+libvmtools_la_LIBADD += ../lib/misc/libMisc.la
 libvmtools_la_LIBADD += @LIBVMTOOLS_LIBADD@
 libvmtools_la_LIBADD += @GLIB2_LIBS@
 libvmtools_la_LIBADD += @ICU_LIBS@
@@ -74,6 +76,7 @@ libvmtools_la_CPPFLAGS += @GLIB2_CPPFLAGS@
 libvmtools_la_LDFLAGS =
 # We require GCC, so we're fine passing compiler-specific flags.
 libvmtools_la_LDFLAGS += -Wl,-z,defs
-# Needed for OS's that don't link shared libraries against libc by default, e.g. FreeBSD
+# Needed for OS's that don't link shared libraries against libc by
+#default, e.g. FreeBSD
 libvmtools_la_LDFLAGS += -Wl,-lc
 
index 659f59a1de8f9df2c2f155c22bb316930cd78f46..22f5b6c53105c36a79fb8f00d335af2a4026b035 100644 (file)
@@ -2913,7 +2913,7 @@ vmxnet_load_multicast (struct net_device *dev)
    struct Vmxnet_Private *lp = netdev_priv(dev);
     volatile u16 *mcast_table = (u16 *)lp->dd->LADRF;
     struct dev_mc_list *dmi = dev->mc_list;
-    char *addrs;
+    u8 *addrs;
     int i, j, bit, byte;
     u32 crc, poly = CRC_POLYNOMIAL_LE;
 
index c51b079681d6f07d61041e0d0ad407de17c4fc49..13f7b4ebc8cc8f81217352acea6bc62bc1b46da4 100644 (file)
@@ -2275,7 +2275,7 @@ vmxnet3_set_mac_addr(struct net_device *netdev, void *p)
        struct vmxnet3_adapter *adapter = compat_netdev_priv(netdev);
 
        memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
-       vmxnet3_write_mac_addr(adapter, addr->sa_data);
+       vmxnet3_write_mac_addr(adapter, netdev->dev_addr);
 
        return 0;
 }
index a5830f1b8ca6c893a6fd7331cb23d428bb285b80..2ce333aea5f6ca3a7138f50c74963660b7ac1ef5 100644 (file)
 
 #define NPA_PLUGIN_NUMPAGES      64
 #define NPA_MEMIO_NUMPAGES       32
-#define NPA_CMD_LOAD_SUCCESS     1
-#define NPA_DEVICE_INFO_LEN      8
+#define VMXNET3_NPA_CMD_SUCCESS   0
+#define VMXNET3_NPA_CMD_FAILURE   1
+#define VMXNET3_PLUGIN_INFO_LEN  32
+// XXX: unify the definitions
 
 /* these structure are versioned using the vmxnet3 version */
 
@@ -65,7 +67,7 @@ struct NPA_PluginConf {
    NPA_PluginPages   pluginPages;
    NPA_MemioPages    memioPages;
    uint64            entryVA;    // address of entry function in the plugin 
-   uint32            deviceInfo[NPA_DEVICE_INFO_LEN]; // opaque data returned by PF driver
+   uint32            deviceInfo[VMXNET3_PLUGIN_INFO_LEN]; // opaque data returned by PF driver
 }
 #include "vmware_pack_end.h"
 NPA_PluginConf;
@@ -73,13 +75,14 @@ NPA_PluginConf;
 
 /* vmkernel and device backend shared definitions */
 
-#define VMXNET3_PLUGIN_NAME_LEN      256
+#define VMXNET3_PLUGIN_NAME_LEN  256
+#define NPA_MEMIO_REGIONS_MAX    6
 
 typedef uint32 VF_ID;
 
 typedef struct Vmxnet3_VFInfo {
    char     pluginName[VMXNET3_PLUGIN_NAME_LEN];
-   uint32   deviceInfo[NPA_DEVICE_INFO_LEN];    // opaque data returned by PF driver
+   uint32   deviceInfo[VMXNET3_PLUGIN_INFO_LEN];    // opaque data returned by PF driver
    MA       memioAddr;
    uint32   memioLen;
 } Vmxnet3_VFInfo;
index 45e246df4e2fc9f94df226cc7a15b7576f247c82..9e147a5d1ee22009ef730bdd7c74a8bbbd8fbf9f 100644 (file)
@@ -106,7 +106,9 @@ typedef enum {
    VMXNET3_CMD_UPDATE_IML,
    VMXNET3_CMD_UPDATE_PMCFG,
    VMXNET3_CMD_UPDATE_FEATURE,
+   VMXNET3_CMD_STOP_EMULATION,
    VMXNET3_CMD_LOAD_PLUGIN,
+   VMXNET3_CMD_ACTIVATE_VF,
 
    VMXNET3_CMD_FIRST_GET = 0xF00D0000,
    VMXNET3_CMD_GET_QUEUE_STATUS = VMXNET3_CMD_FIRST_GET,
index a223de54d9815f8013469c616ed321bc391caa32..2540c994bc6b2c59248ea02962ae5c19188e5de6 100644 (file)
@@ -38,6 +38,8 @@ COMMON += ../lib/dict/libDict.la
 COMMON += ../lib/message/libMessage.la
 COMMON += ../lib/unicode/libUnicode.la
 COMMON += ../lib/sync/libSync.la
+COMMON += ../lib/lock/libLock.la
+COMMON += ../lib/nothread/libNothread.la
 COMMON += ../lib/misc/libMisc.la
 COMMON += ../lib/panicDefault/libPanicDefault.la
 COMMON += ../lib/panic/libPanic.la
index c0781beec379a74aa74632a8ee753b57fa852222..11587dc8ca0b84139735f9862c9cd584f724799e 100644 (file)
@@ -85,7 +85,6 @@ vmware_user_LDADD += ../lib/hgfs/libHgfs.la
 vmware_user_LDADD += ../lib/message/libMessage.la
 vmware_user_LDADD += ../lib/unicode/libUnicode.la
 vmware_user_LDADD += ../lib/auth/libAuth.la
-vmware_user_LDADD += ../lib/misc/libMisc.la
 vmware_user_LDADD += ../lib/procMgr/libProcMgr.la
 vmware_user_LDADD += ../lib/panicDefault/libPanicDefault.la
 vmware_user_LDADD += ../lib/panic/libPanic.la
@@ -96,12 +95,18 @@ if ENABLE_UNITY
    vmware_user_LDADD += ../lib/raster/libRaster.la
    vmware_user_LDADD += ../lib/region/libRegion.la
 endif
+
 vmware_user_LDADD += -lcrypt
 vmware_user_LDADD += -lstdc++
 if USE_SLASH_PROC
    vmware_user_LDADD += -lgcc_s
    vmware_user_LDADD += ../lib/slashProc/libSlashProc.la
 endif
+
+vmware_user_LDADD += ../lib/lock/libLock.la
+vmware_user_LDADD += ../lib/nothread/libNothread.la
+vmware_user_LDADD += ../lib/misc/libMisc.la
+
 vmware_user_LDADD += @GTK_LIBS@
 if HAVE_GTKMM
    vmware_user_LDADD += @GTKMM_LIBS@