diff -Naur a/lib/glibUtils/fileLogger.c b/lib/glibUtils/fileLogger.c
--- a/lib/glibUtils/fileLogger.c	2015-11-24 07:59:42.000000000 +0100
+++ b/lib/glibUtils/fileLogger.c	2016-01-15 10:22:59.976153011 +0100
@@ -44,7 +44,7 @@
    guint          maxFiles;
    gboolean       append;
    gboolean       error;
-   GStaticMutex   lock;
+   GMutex         lock;
 } FileLogger;
 
 
@@ -327,7 +327,7 @@
    FileLogger *logger = data;
    gsize written;
 
-   g_static_mutex_lock(&logger->lock);
+   g_mutex_lock(&logger->lock);
 
    if (logger->error) {
       goto exit;
@@ -366,7 +366,7 @@
    }
 
 exit:
-   g_static_mutex_unlock(&logger->lock);
+   g_mutex_unlock(&logger->lock);
 }
 
 
@@ -388,7 +388,7 @@
    if (logger->file != NULL) {
       g_io_channel_unref(logger->file);
    }
-   g_static_mutex_free(&logger->lock);
+   g_mutex_free(&logger->lock);
    g_free(logger->path);
    g_free(logger);
 }
@@ -435,7 +435,7 @@
    data->append = append;
    data->maxSize = maxSize * 1024 * 1024;
    data->maxFiles = maxFiles + 1; /* To account for the active log file. */
-   g_static_mutex_init(&data->lock);
+   g_mutex_init(&data->lock);
 
    return &data->handler;
 }
diff -Naur a/lib/glibUtils/stdLogger.c b/lib/glibUtils/stdLogger.c
--- a/lib/glibUtils/stdLogger.c	2015-11-24 07:59:42.000000000 +0100
+++ b/lib/glibUtils/stdLogger.c	2016-01-15 10:24:07.078256206 +0100
@@ -66,12 +66,12 @@
    StdLogger *sdata = data;
 
    if (!sdata->attached) {
-      g_static_mutex_lock(&gConsoleLock);
+      g_mutex_lock(&gConsoleLock);
       if (gRefCount != 0 || GlibUtils_AttachConsole()) {
          gRefCount++;
          sdata->attached = TRUE;
       }
-      g_static_mutex_unlock(&gConsoleLock);
+      g_mutex_unlock(&gConsoleLock);
    }
 
    if (!sdata->attached) {
@@ -105,11 +105,11 @@
 {
 #if defined(_WIN32)
    StdLogger *sdata = data;
-   g_static_mutex_lock(&gConsoleLock);
+   g_mutex_lock(&gConsoleLock);
    if (sdata->attached && --gRefCount == 0) {
       FreeConsole();
    }
-   g_static_mutex_unlock(&gConsoleLock);
+   g_mutex_unlock(&gConsoleLock);
 #endif
    g_free(data);
 }
diff -Naur a/lib/glibUtils/sysLogger.c b/lib/glibUtils/sysLogger.c
--- a/lib/glibUtils/sysLogger.c	2015-11-24 07:59:42.000000000 +0100
+++ b/lib/glibUtils/sysLogger.c	2016-01-15 10:37:53.148968674 +0100
@@ -38,7 +38,7 @@
 
 
 static SysLogger *gSysLogger;
-static GStaticMutex gSysLoggerLock = G_STATIC_MUTEX_INIT;
+static GMutex gSysLoggerLock;
 
 
 /*
@@ -105,7 +105,7 @@
 {
    g_return_if_fail(data == gSysLogger);
    g_return_if_fail(gSysLogger->refcount > 0);
-   g_static_mutex_lock(&gSysLoggerLock);
+   g_mutex_lock(&gSysLoggerLock);
    gSysLogger->refcount -= 1;
    if (gSysLogger->refcount == 0) {
       closelog();
@@ -113,7 +113,7 @@
       g_free(gSysLogger);
       gSysLogger = NULL;
    }
-   g_static_mutex_unlock(&gSysLoggerLock);
+   g_mutex_unlock(&gSysLoggerLock);
 }
 
 
@@ -140,7 +140,7 @@
 GlibUtils_CreateSysLogger(const char *domain,
                           const char *facility)
 {
-   g_static_mutex_lock(&gSysLoggerLock);
+   g_mutex_lock(&gSysLoggerLock);
    if (gSysLogger == NULL) {
       int facid = LOG_USER;
 
@@ -203,7 +203,7 @@
    } else {
       gSysLogger->refcount += 1;
    }
-   g_static_mutex_unlock(&gSysLoggerLock);
+   g_mutex_unlock(&gSysLoggerLock);
    return &gSysLogger->handler;
 }
 
diff -Naur a/lib/rpcChannel/rpcChannelInt.h b/lib/rpcChannel/rpcChannelInt.h
--- a/lib/rpcChannel/rpcChannelInt.h	2015-11-24 07:59:42.000000000 +0100
+++ b/lib/rpcChannel/rpcChannelInt.h	2016-01-15 11:30:31.403376775 +0100
@@ -53,7 +53,7 @@
    GMainContext              *mainCtx;
    const char                *appName;
    gpointer                  appCtx;
-   GStaticMutex              outLock;
+   GMutex                    outLock;
    struct RpcIn              *in;
    gboolean                  inStarted;
    gboolean                  outStarted;
diff -Naur a/libvmtools/vmtoolsLog.c b/libvmtools/vmtoolsLog.c
--- a/libvmtools/vmtoolsLog.c	2015-11-24 07:59:42.000000000 +0100
+++ b/libvmtools/vmtoolsLog.c	2016-01-15 11:34:45.221864504 +0100
@@ -160,7 +160,7 @@
 static LogHandler *gErrorSyslog;
 static GPtrArray *gDomains = NULL;
 static gboolean gLogInitialized = FALSE;
-static GStaticRecMutex gLogStateMutex = G_STATIC_REC_MUTEX_INIT;
+static GRecMutex gLogStateMutex;
 static gboolean gLoggingStopped = FALSE;
 static gboolean gLogIOSuspended = FALSE;
 
@@ -1055,7 +1055,7 @@
    gLogEnabled |= force;
    if (!gLogInitialized) {
       gLogInitialized = TRUE;
-      g_static_rec_mutex_init(&gLogStateMutex);
+      g_rec_mutex_init(&gLogStateMutex);
    }
 
    gMaxCacheEntries = g_key_file_get_integer(cfg, LOGGING_GROUP,
@@ -1221,7 +1221,7 @@
 void
 VMTools_AcquireLogStateLock(void)
 {
-   g_static_rec_mutex_lock(&gLogStateMutex);
+   g_rec_mutex_lock(&gLogStateMutex);
 }
 
 
@@ -1232,7 +1232,7 @@
 void
 VMTools_ReleaseLogStateLock(void)
 {
-   g_static_rec_mutex_unlock(&gLogStateMutex);
+   g_rec_mutex_unlock(&gLogStateMutex);
 }
 
 
diff -Naur a/libvmtools/i18n.c b/libvmtools/i18n.c
--- a/libvmtools/i18n.c	2015-11-24 07:59:42.000000000 +0100
+++ b/libvmtools/i18n.c	2016-01-15 11:37:18.900142179 +0100
@@ -54,7 +54,7 @@
 
 typedef struct MsgState {
    HashTable     *domains; /* List of text domains. */
-   GStaticMutex   lock;    /* Mutex to protect shared state. */
+   GMutex        lock;    /* Mutex to protect shared state. */
 } MsgState;
 
 
@@ -132,7 +132,7 @@
 {
    ASSERT(gMsgState == NULL);
    gMsgState = g_new0(MsgState, 1);
-   g_static_mutex_init(&gMsgState->lock);
+   g_mutex_init(&gMsgState->lock);
    return NULL;
 }
 
@@ -343,7 +343,7 @@
     * This lock is pretty coarse-grained, but a lot of the code below just runs
     * in exceptional situations, so it should be OK.
     */
-   g_static_mutex_lock(&state->lock);
+   g_mutex_lock(&state->lock);
 
    catalog = MsgGetCatalog(domain);
    if (catalog != NULL) {
@@ -414,7 +414,7 @@
       }
    }
 
-   g_static_mutex_unlock(&state->lock);
+   g_mutex_unlock(&state->lock);
 
    return strp;
 }
@@ -681,7 +681,7 @@
       if (gMsgState->domains != NULL) {
          HashTable_Free(gMsgState->domains);
       }
-      g_static_mutex_free(&gMsgState->lock);
+      g_mutex_free(&gMsgState->lock);
       g_free(gMsgState);
    }
 }
@@ -774,9 +774,9 @@
                    "catalog dir '%s'.\n", domain, lang, catdir);
       }
    } else {
-      g_static_mutex_lock(&state->lock);
+      g_mutex_lock(&state->lock);
       MsgSetCatalog(domain, catalog);
-      g_static_mutex_unlock(&state->lock);
+      g_mutex_unlock(&state->lock);
    }
    g_free(file);
    free(dfltdir);
diff -Naur a/lib/rpcChannel/rpcChannel.c b/lib/rpcChannel/rpcChannel.c
--- a/lib/rpcChannel/rpcChannel.c	2015-11-24 07:59:42.000000000 +0100
+++ b/lib/rpcChannel/rpcChannel.c	2016-01-15 11:46:08.061147289 +0100
@@ -675,7 +675,7 @@
    chan = BackdoorChannel_New();
 #endif
    if (chan) {
-      g_static_mutex_init(&chan->outLock);
+      g_mutex_init(&chan->outLock);
    }
    return chan;
 }
@@ -691,7 +691,7 @@
 RpcChannel_Shutdown(RpcChannel *chan)
 {
    if (chan != NULL) {
-      g_static_mutex_free(&chan->outLock);
+      g_mutex_free(&chan->outLock);
    }
 
    if (chan != NULL && chan->funcs != NULL && chan->funcs->shutdown != NULL) {
@@ -776,7 +776,7 @@
    g_return_if_fail(chan->funcs != NULL);
    g_return_if_fail(chan->funcs->stop != NULL);
 
-   g_static_mutex_lock(&chan->outLock);
+   g_mutex_lock(&chan->outLock);
    chan->funcs->stop(chan);
 
    if (chan->in != NULL) {
@@ -787,7 +787,7 @@
    } else {
       ASSERT(!chan->inStarted);
    }
-   g_static_mutex_unlock(&chan->outLock);
+   g_mutex_unlock(&chan->outLock);
 }
 
 
@@ -853,7 +853,7 @@
 
    ASSERT(chan && chan->funcs);
 
-   g_static_mutex_lock(&chan->outLock);
+   g_mutex_lock(&chan->outLock);
 
    funcs = chan->funcs;
    ASSERT(funcs->send);
@@ -902,7 +902,7 @@
    }
 
 exit:
-   g_static_mutex_unlock(&chan->outLock);
+   g_mutex_unlock(&chan->outLock);
    return ok;
 }
 
diff -Naur a/lib/rpcChannel/rpcChannel.c.save b/lib/rpcChannel/rpcChannel.c.save
--- a/lib/rpcChannel/rpcChannel.c.save	1970-01-01 01:00:00.000000000 +0100
+++ b/lib/rpcChannel/rpcChannel.c.save	2016-01-15 11:44:57.245012048 +0100
@@ -0,0 +1,1049 @@
+/*********************************************************
+ * Copyright (C) 2008-2015 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.
+ *
+ *********************************************************/
+
+/**
+ * @file rpcChannel.c
+ *
+ *    Common functions to all RPC channel implementations.
+ */
+
+#include <string.h>
+#include "vm_assert.h"
+#include "dynxdr.h"
+#include "rpcChannelInt.h"
+#include "str.h"
+#include "strutil.h"
+#include "vmxrpc.h"
+#include "xdrutil.h"
+#include "rpcin.h"
+#include "debug.h"
+
+/** Internal state of a channel. */
+typedef struct RpcChannelInt {
+   RpcChannel              impl;
+   gchar                  *appName;
+   GHashTable             *rpcs;
+   GMainContext           *mainCtx;
+   GSource                *resetCheck;
+   gpointer                appCtx;
+   RpcChannelCallback      resetReg;
+   RpcChannelResetCb       resetCb;
+   gpointer                resetData;
+   gboolean                rpcError;
+   guint                   rpcErrorCount;
+} RpcChannelInt;
+
+/** Max number of times to attempt a channel restart. */
+#define RPCIN_MAX_RESTARTS 60
+
+#define LGPFX "RpcChannel: "
+
+static gboolean
+RpcChannelPing(RpcInData *data);
+
+static RpcChannelCallback gRpcHandlers[] =  {
+   { "ping", RpcChannelPing, NULL, NULL, NULL, 0 }
+};
+
+static gboolean gUseBackdoorOnly = FALSE;
+
+/*
+ * Track the vSocket connection failure, so that we can
+ * avoid using vSockets until a channel reset/restart or
+ * the service itself gets restarted.
+ */
+static gboolean gVSocketFailed = FALSE;
+
+/**
+ * Handler for a "ping" message. Does nothing.
+ *
+ * @param[in]  data     The RPC data.
+ *
+ * @return TRUE.
+ */
+
+static gboolean
+RpcChannelPing(RpcInData *data)
+{
+   return RPCIN_SETRETVALS(data, "", TRUE);
+}
+
+
+/**
+ * Callback for restarting the RPC channel.
+ *
+ * @param[in]  _chan    The RPC channel
+ *
+ * @return FALSE
+ */
+
+static gboolean
+RpcChannelRestart(gpointer _chan)
+{
+   RpcChannelInt *chan = _chan;
+
+   RpcChannel_Stop(&chan->impl);
+   /* Clear vSocket channel failure */
+   Debug(LGPFX "Clearing backdoor behavior ...\n");
+   gVSocketFailed = FALSE;
+
+   if (!RpcChannel_Start(&chan->impl)) {
+      Warning("Channel restart failed [%d]\n", chan->rpcErrorCount);
+      if (chan->resetCb != NULL) {
+         chan->resetCb(&chan->impl, FALSE, chan->resetData);
+      }
+   } else {
+      chan->rpcError = FALSE;
+   }
+
+   return FALSE;
+}
+
+
+/**
+ * Checks and potentially resets the RPC channel. This code is based on the
+ * toolsDaemon.c function "ToolsDaemon_CheckReset".
+ *
+ * @param[in]  _chan    The RPC channel.
+ *
+ * @return FALSE. The reset callback will schedule a new check when it's called.
+ */
+
+static gboolean
+RpcChannelCheckReset(gpointer _chan)
+{
+   static int channelTimeoutAttempts = RPCIN_MAX_RESTARTS;
+   RpcChannelInt *chan = _chan;
+
+   /* Check the channel state. */
+   if (chan->rpcError) {
+      GSource *src;
+
+      if (++(chan->rpcErrorCount) > channelTimeoutAttempts) {
+         Warning("Failed to reset channel after %u attempts\n",
+                 chan->rpcErrorCount - 1);
+         if (chan->resetCb != NULL) {
+            chan->resetCb(&chan->impl, FALSE, chan->resetData);
+         }
+         goto exit;
+      }
+
+      /* Schedule the channel restart for 1 sec in the future. */
+      Debug(LGPFX "Resetting channel [%u]\n", chan->rpcErrorCount);
+      src = g_timeout_source_new(1000);
+      g_source_set_callback(src, RpcChannelRestart, chan, NULL);
+      g_source_attach(src, chan->mainCtx);
+      g_source_unref(src);
+      goto exit;
+   }
+
+   /* Reset was successful. */
+   Debug(LGPFX "Channel was reset successfully.\n");
+   chan->rpcErrorCount = 0;
+   Debug(LGPFX "Clearing backdoor behavior ...\n");
+   gVSocketFailed = FALSE;
+
+   if (chan->resetCb != NULL) {
+      chan->resetCb(&chan->impl, TRUE, chan->resetData);
+   }
+
+exit:
+   g_source_unref(chan->resetCheck);
+   chan->resetCheck = NULL;
+   return FALSE;
+}
+
+
+/**
+ * Handles an RPC reset. Calls the reset callback of all loaded plugins.
+ *
+ * @param[in]  data     The RPC data.
+ *
+ * @return TRUE.
+ */
+
+static gboolean
+RpcChannelReset(RpcInData *data)
+{
+   gchar *msg;
+   RpcChannelInt *chan = data->clientData;
+
+   if (chan->resetCheck == NULL) {
+      chan->resetCheck = g_idle_source_new();
+      g_source_set_priority(chan->resetCheck, G_PRIORITY_HIGH);
+      g_source_set_callback(chan->resetCheck, RpcChannelCheckReset, chan, NULL);
+      g_source_attach(chan->resetCheck, chan->mainCtx);
+   }
+
+   msg = Str_Asprintf(NULL, "ATR %s", chan->appName);
+   ASSERT_MEM_ALLOC(msg);
+   return RPCIN_SETRETVALSF(data, msg, TRUE);
+}
+
+
+/**
+ * A wrapper for standard RPC callback functions which provides automatic
+ * XDR serialization / deserialization if requested by the application.
+ *
+ * @param[in]  data     RpcIn data.
+ * @param[in]  rpc      The RPC registration data.
+ *
+ * @return Whether the RPC was handled successfully.
+ */
+
+static Bool
+RpcChannelXdrWrapper(RpcInData *data,
+                     RpcChannelCallback *rpc)
+{
+   Bool ret;
+   RpcInData copy;
+   void *xdrData = NULL;
+
+   if (rpc->xdrIn != NULL) {
+      xdrData = malloc(rpc->xdrInSize);
+      if (xdrData == NULL) {
+         ret = RPCIN_SETRETVALS(data, "Out of memory.", FALSE);
+         goto exit;
+      }
+
+      memset(xdrData, 0, rpc->xdrInSize);
+      if (!XdrUtil_Deserialize(data->args + 1, data->argsSize - 1,
+                               rpc->xdrIn, xdrData)) {
+         ret = RPCIN_SETRETVALS(data, "XDR deserialization failed.", FALSE);
+         free(xdrData);
+         goto exit;
+      }
+
+      copy.name = data->name;
+      copy.args = xdrData;
+      copy.argsSize = rpc->xdrInSize;
+      copy.result = data->result;
+      copy.resultLen = data->resultLen;
+      copy.freeResult = data->freeResult;
+      copy.appCtx = data->appCtx;
+      copy.clientData = rpc->clientData;
+   } else {
+      memcpy(&copy, data, sizeof copy);
+   }
+
+   ret = rpc->callback(&copy);
+
+   if (rpc->xdrIn != NULL) {
+      VMX_XDR_FREE(rpc->xdrIn, xdrData);
+      free(xdrData);
+      copy.args = NULL;
+      data->result = copy.result;
+      data->resultLen = copy.resultLen;
+      data->freeResult = copy.freeResult;
+   }
+
+   if (rpc->xdrOut != NULL && copy.result != NULL) {
+      XDR xdrs;
+      xdrproc_t xdrProc = rpc->xdrOut;
+
+      if (DynXdr_Create(&xdrs) == NULL) {
+         ret = RPCIN_SETRETVALS(data, "Out of memory.", FALSE);
+         goto exit;
+      }
+
+      if (!xdrProc(&xdrs, copy.result)) {
+         ret = RPCIN_SETRETVALS(data, "XDR serialization failed.", FALSE);
+         DynXdr_Destroy(&xdrs, TRUE);
+         goto exit;
+      }
+
+      if (copy.freeResult) {
+         VMX_XDR_FREE(rpc->xdrOut, copy.result);
+      }
+      data->result = DynXdr_Get(&xdrs);
+      data->resultLen = XDR_GETPOS(&xdrs);
+      data->freeResult = TRUE;
+      DynXdr_Destroy(&xdrs, FALSE);
+   }
+
+exit:
+   if (copy.freeResult && copy.result != NULL) {
+      g_free(copy.result);
+   }
+   return ret;
+}
+
+
+/**
+ * Builds an "rpcout" command to send a XDR struct.
+ *
+ * @param[in]  cmd         The command name.
+ * @param[in]  xdrProc     Function to use for serializing the XDR struct.
+ * @param[in]  xdrData     The XDR struct to serialize.
+ * @param[out] result      Where to store the serialized data.
+ * @param[out] resultLen   Where to store the serialized data length.
+ *
+ * @return Whether successfully built the command.
+ */
+
+gboolean
+RpcChannel_BuildXdrCommand(const char *cmd,
+                           void *xdrProc,
+                           void *xdrData,
+                           char **result,
+                           size_t *resultLen)
+{
+   Bool ret = FALSE;
+   xdrproc_t proc = xdrProc;
+   XDR xdrs;
+
+   if (DynXdr_Create(&xdrs) == NULL) {
+      return FALSE;
+   }
+
+   if (!DynXdr_AppendRaw(&xdrs, cmd, strlen(cmd))) {
+      goto exit;
+   }
+
+   if (!DynXdr_AppendRaw(&xdrs, " ", 1)) {
+      goto exit;
+   }
+
+   if (!proc(&xdrs, xdrData)) {
+      goto exit;
+   }
+
+   *result = DynXdr_Get(&xdrs);
+   *resultLen = xdr_getpos(&xdrs);
+
+   ret = TRUE;
+
+exit:
+   DynXdr_Destroy(&xdrs, !ret);
+   return ret;
+}
+
+
+/**
+ * Creates a new RpcChannel without any implementation.
+ *
+ * This is mainly for use of code that is implementing a custom RpcChannel.
+ * Such implementations should provide their own "constructor"-type function
+ * which should then call this function to get an RpcChannel instance. They
+ * should then fill in the function pointers that provide the implementation
+ * for the channel before making the channel available to the callers.
+ *
+ * @return A new RpcChannel instance.
+ */
+
+RpcChannel *
+RpcChannel_Create(void)
+{
+   RpcChannelInt *chan = g_new0(RpcChannelInt, 1);
+   return &chan->impl;
+}
+
+
+/**
+ * Dispatches the given RPC to the registered handler. This mimics the behavior
+ * of the RpcIn library (but is not tied to that particular implementation of
+ * an RPC channel).
+ *
+ * @param[in,out]    data     The RPC data.
+ *
+ * @return Whether the RPC was handled successfully.
+ */
+
+gboolean
+RpcChannel_Dispatch(RpcInData *data)
+{
+   char *name = NULL;
+   unsigned int index = 0;
+   size_t nameLen;
+   Bool status;
+   RpcChannelCallback *rpc = NULL;
+   RpcChannelInt *chan = data->clientData;
+
+   name = StrUtil_GetNextToken(&index, data->args, " ");
+   if (name == NULL) {
+      Debug(LGPFX "Bad command (null) received.\n");
+      status = RPCIN_SETRETVALS(data, "Bad command", FALSE);
+      goto exit;
+   }
+
+   if (chan->rpcs != NULL) {
+      rpc = g_hash_table_lookup(chan->rpcs, name);
+   }
+
+   if (rpc == NULL) {
+      Debug(LGPFX "Unknown Command '%s': Handler not registered.\n", name);
+      status = RPCIN_SETRETVALS(data, "Unknown Command", FALSE);
+      goto exit;
+   }
+
+   /* Adjust the RPC arguments. */
+   nameLen = strlen(name);
+   data->name = name;
+   data->args = data->args + nameLen;
+   data->argsSize -= nameLen;
+   data->appCtx = chan->appCtx;
+   data->clientData = rpc->clientData;
+
+   if (rpc->xdrIn != NULL || rpc->xdrOut != NULL) {
+      status = RpcChannelXdrWrapper(data, rpc);
+   } else {
+      status = rpc->callback(data);
+   }
+
+   ASSERT(data->result != NULL);
+
+exit:
+   data->name = NULL;
+   free(name);
+   return status;
+}
+
+
+/**
+ * Shuts down an RPC channel and release any held resources.
+ *
+ * @param[in]  chan     The RPC channel.
+ *
+ * @return  Whether the channel was shut down successfully.
+ */
+
+gboolean
+RpcChannel_Destroy(RpcChannel *chan)
+{
+   size_t i;
+   RpcChannelInt *cdata = (RpcChannelInt *) chan;
+
+   if (cdata->impl.funcs != NULL && cdata->impl.funcs->shutdown != NULL) {
+      cdata->impl.funcs->shutdown(chan);
+   }
+
+   RpcChannel_UnregisterCallback(chan, &cdata->resetReg);
+   for (i = 0; i < ARRAYSIZE(gRpcHandlers); i++) {
+      RpcChannel_UnregisterCallback(chan, &gRpcHandlers[i]);
+   }
+
+   if (cdata->rpcs != NULL) {
+      g_hash_table_destroy(cdata->rpcs);
+      cdata->rpcs = NULL;
+   }
+
+   cdata->resetCb = NULL;
+   cdata->resetData = NULL;
+   cdata->appCtx = NULL;
+
+   g_free(cdata->appName);
+   cdata->appName = NULL;
+
+   if (cdata->mainCtx != NULL) {
+      g_main_context_unref(cdata->mainCtx);
+      cdata->mainCtx = NULL;
+   }
+
+   if (cdata->resetCheck != NULL) {
+      g_source_destroy(cdata->resetCheck);
+      cdata->resetCheck = NULL;
+   }
+
+   g_free(cdata);
+   return TRUE;
+}
+
+
+/**
+ * Error handling function for the RPC channel. Enqueues the "check reset"
+ * function for running later, if it's not yet enqueued.
+ *
+ * @param[in]  _chan       The RPC channel.
+ * @param[in]  status      Error description.
+ */
+
+void
+RpcChannel_Error(void *_chan,
+                 char const *status)
+{
+   RpcChannelInt *chan = _chan;
+   chan->rpcError = TRUE;
+   /*
+    * XXX: Workaround for PR 935520.
+    * Revert the log call to Warning() after fixing PR 955746.
+    */
+   Debug(LGPFX "Error in the RPC receive loop: %s.\n", status);
+
+   if (chan->resetCheck == NULL) {
+      chan->resetCheck = g_idle_source_new();
+      g_source_set_callback(chan->resetCheck, RpcChannelCheckReset, chan, NULL);
+      g_source_attach(chan->resetCheck, chan->mainCtx);
+   }
+}
+
+
+/**
+ * Initializes the RPC channel for inbound operations.
+ *
+ * This function must be called before starting the channel if the application
+ * wants to receive messages on the channel. Applications don't need to call it
+ * if only using the outbound functionality.
+ *
+ * @param[in]  chan        The RPC channel.
+ * @param[in]  appName     TCLO application name.
+ * @param[in]  mainCtx     Application event context.
+ * @param[in]  appCtx      Application context.
+ * @param[in]  resetCb     Callback for when a reset occurs.
+ * @param[in]  resetData   Client data for the reset callback.
+ */
+
+void
+RpcChannel_Setup(RpcChannel *chan,
+                 const gchar *appName,
+                 GMainContext *mainCtx,
+                 gpointer appCtx,
+                 RpcChannelResetCb resetCb,
+                 gpointer resetData)
+{
+   size_t i;
+   RpcChannelInt *cdata = (RpcChannelInt *) chan;
+
+   cdata->appName = g_strdup(appName);
+   cdata->appCtx = appCtx;
+   cdata->mainCtx = g_main_context_ref(mainCtx);
+   cdata->resetCb = resetCb;
+   cdata->resetData = resetData;
+
+   cdata->resetReg.name = "reset";
+   cdata->resetReg.callback = RpcChannelReset;
+   cdata->resetReg.clientData = chan;
+
+   /* Register the callbacks handled by the rpcChannel library. */
+   RpcChannel_RegisterCallback(chan, &cdata->resetReg);
+
+   for (i = 0; i < ARRAYSIZE(gRpcHandlers); i++) {
+      RpcChannel_RegisterCallback(chan, &gRpcHandlers[i]);
+   }
+
+   if (chan->funcs != NULL && chan->funcs->setup != NULL) {
+      chan->funcs->setup(chan, mainCtx, appName, appCtx);
+   } else {
+      chan->mainCtx = g_main_context_ref(mainCtx);
+      chan->in = RpcIn_Construct(mainCtx, RpcChannel_Dispatch, chan);
+      ASSERT(chan->in != NULL);
+   }
+}
+
+
+/**
+ * Sets the non-freeable result of the given RPC context to the given value.
+ * The result should be a NULL-terminated string.
+ *
+ * @param[in] data     RPC context.
+ * @param[in] result   Result string.
+ * @param[in] retVal   Return value of this function.
+ *
+ * @return @a retVal
+ */
+
+gboolean
+RpcChannel_SetRetVals(RpcInData *data,
+                      char const *result,
+                      gboolean retVal)
+{
+   ASSERT(data);
+
+   /* This cast is safe: data->result will not be freed. */
+   data->result = (char *)result;
+   data->resultLen = strlen(data->result);
+   data->freeResult = FALSE;
+
+   return retVal;
+}
+
+
+/**
+ * Sets the freeable result of the given RPC context to the given value.
+ * The result should be a NULL-terminated string.
+ *
+ * @param[in] data     RPC context.
+ * @param[in] result   Result string.
+ * @param[in] retVal   Return value of this function.
+ *
+ * @return @a retVal
+ */
+
+gboolean
+RpcChannel_SetRetValsF(RpcInData *data,
+                       char *result,
+                       gboolean retVal)
+{
+   ASSERT(data);
+
+   data->result = result;
+   data->resultLen = strlen(data->result);
+   data->freeResult = TRUE;
+
+   return retVal;
+}
+
+
+/**
+ * Registers a new RPC handler in the given RPC channel. This function is
+ * not thread-safe.
+ *
+ * @param[in]  chan     The channel instance.
+ * @param[in]  rpc      Info about the RPC being registered.
+ */
+
+void
+RpcChannel_RegisterCallback(RpcChannel *chan,
+                            RpcChannelCallback *rpc)
+{
+   RpcChannelInt *cdata = (RpcChannelInt *) chan;
+   ASSERT(rpc->name != NULL && strlen(rpc->name) > 0);
+   ASSERT(rpc->callback);
+   ASSERT(rpc->xdrIn == NULL || rpc->xdrInSize > 0);
+   if (cdata->rpcs == NULL) {
+      cdata->rpcs = g_hash_table_new(g_str_hash, g_str_equal);
+   }
+   if (g_hash_table_lookup(cdata->rpcs, rpc->name) != NULL) {
+      Panic("Trying to overwrite existing RPC registration for %s!\n", rpc->name);
+   }
+   g_hash_table_insert(cdata->rpcs, (gpointer) rpc->name, rpc);
+}
+
+
+/**
+ * Unregisters a new RPC handler from the given RPC channel. This function is
+ * not thread-safe.
+ *
+ * @param[in]  chan     The channel instance.
+ * @param[in]  rpc      Info about the RPC being unregistered.
+ */
+
+void
+RpcChannel_UnregisterCallback(RpcChannel *chan,
+                              RpcChannelCallback *rpc)
+{
+   RpcChannelInt *cdata = (RpcChannelInt *) chan;
+   if (cdata->rpcs != NULL) {
+      g_hash_table_remove(cdata->rpcs, rpc->name);
+   }
+}
+
+
+/**
+ * Force to create backdoor channels only.
+ * This provides a kill-switch to disable vsocket channels if needed.
+ * This needs to be called before RpcChannel_New to take effect.
+ */
+
+void
+RpcChannel_SetBackdoorOnly(void)
+{
+   gUseBackdoorOnly = TRUE;
+   Debug(LGPFX "Using vsocket is disabled.\n");
+}
+
+
+/**
+ * Create an RpcChannel instance using a prefered channel implementation,
+ * currently this is VSockChannel.
+ *
+ * @return  RpcChannel
+ */
+
+RpcChannel *
+RpcChannel_New(void)
+{
+   RpcChannel *chan;
+#if (defined(__linux__) && !defined(USERWORLD)) || defined(_WIN32)
+   chan = (gUseBackdoorOnly || gVSocketFailed) ?
+          BackdoorChannel_New() : VSockChannel_New();
+#else
+   chan = BackdoorChannel_New();
+#endif
+   if (chan) {
+      g_mutex_init(&chan->outLock);
+   }
+   return chan;
+}
+
+
+/**
+ * Wrapper for the shutdown function of an RPC channel struct.
+ *
+ * @param[in]  chan        The RPC channel instance.
+ */
+
+void
+RpcChannel_Shutdown(RpcChannel *chan)
+{
+   if (chan != NULL) {
+      g_static_mutex_free(&chan->outLock);
+   }
+
+   if (chan != NULL && chan->funcs != NULL && chan->funcs->shutdown != NULL) {
+      if (chan->in != NULL) {
+         if (chan->inStarted) {
+            RpcIn_stop(chan->in);
+         }
+         chan->inStarted = FALSE;
+         RpcIn_Destruct(chan->in);
+         chan->in = NULL;
+      } else {
+         ASSERT(!chan->inStarted);
+      }
+
+      if (chan->mainCtx != NULL) {
+         g_main_context_unref(chan->mainCtx);
+      }
+      chan->funcs->shutdown(chan);
+   }
+}
+
+
+/**
+ * Start an RPC channel. We may fallback to backdoor channel when other type
+ * of channel fails to start.
+ *
+ * @param[in]  chan        The RPC channel instance.
+ *
+ * @return TRUE on success.
+ */
+
+gboolean
+RpcChannel_Start(RpcChannel *chan)
+{
+   gboolean ok;
+   const RpcChannelFuncs *funcs;
+
+   if (chan == NULL || chan->funcs == NULL || chan->funcs->start == NULL) {
+      return FALSE;
+   }
+
+   if (chan->outStarted) {
+      /* Already started. Make sure both channels are in sync and return. */
+      ASSERT(chan->in == NULL || chan->inStarted);
+      return TRUE;
+   }
+
+   if (chan->in != NULL && !chan->inStarted) {
+      ok = RpcIn_start(chan->in, RPCIN_MAX_DELAY, RpcChannel_Error, chan);
+      chan->inStarted = ok;
+   }
+
+   funcs = chan->funcs;
+   ok = funcs->start(chan);
+
+   if (!ok && funcs->onStartErr != NULL) {
+      Debug(LGPFX "Fallback to backdoor ...\n");
+      funcs->onStartErr(chan);
+      ok = BackdoorChannel_Fallback(chan);
+      /*
+       * As vSocket is not available, we stick the backdoor
+       * behavior until the channel is reset/restarted.
+       */
+      Debug(LGPFX "Sticking backdoor behavior ...\n");
+      gVSocketFailed = TRUE;
+   }
+
+   return ok;
+}
+
+
+/**
+ * Wrapper for the stop function of an RPC channel struct.
+ *
+ * @param[in]  chan        The RPC channel instance.
+ */
+
+void
+RpcChannel_Stop(RpcChannel *chan)
+{
+   g_return_if_fail(chan != NULL);
+   g_return_if_fail(chan->funcs != NULL);
+   g_return_if_fail(chan->funcs->stop != NULL);
+
+   g_static_mutex_lock(&chan->outLock);
+   chan->funcs->stop(chan);
+
+   if (chan->in != NULL) {
+      if (chan->inStarted) {
+         RpcIn_stop(chan->in);
+      }
+      chan->inStarted = FALSE;
+   } else {
+      ASSERT(!chan->inStarted);
+   }
+   g_static_mutex_unlock(&chan->outLock);
+}
+
+
+/**
+ * Wrapper for get channel type function of an RPC channel struct.
+ *
+ * @param[in]  chan        The RPC channel instance.
+ */
+
+RpcChannelType
+RpcChannel_GetType(RpcChannel *chan)
+{
+   if (chan == NULL || chan->funcs == NULL || chan->funcs->getType == NULL) {
+      return RPCCHANNEL_TYPE_INACTIVE;
+   }
+   return chan->funcs->getType(chan);
+}
+
+
+/**
+ * Free the allocated memory for the results from RpcChannel_Send* calls.
+ *
+ * @param[in] ptr   result from RpcChannel_Send* calls.
+ *
+ * @return none
+ */
+
+void
+RpcChannel_Free(void *ptr)
+{
+   free(ptr);
+}
+
+
+/**
+ * Send function of an RPC channel struct. Retry once if it fails for
+ * non-backdoor Channels. Backdoor channel already tries inside. A second try
+ * may create a different type of channel.
+ *
+ * @param[in]  chan        The RPC channel instance.
+ * @param[in]  data        Data to send.
+ * @param[in]  dataLen     Number of bytes to send.
+ * @param[out] result      Response from other side (should be freed by
+ *                         calling RpcChannel_Free).
+ * @param[out] resultLen   Number of bytes in response.
+ *
+ * @return The status from the remote end (TRUE if call was successful).
+ */
+
+gboolean
+RpcChannel_Send(RpcChannel *chan,
+                char const *data,
+                size_t dataLen,
+                char **result,
+                size_t *resultLen)
+{
+   gboolean ok;
+   char *res = NULL;
+   size_t resLen = 0;
+   const RpcChannelFuncs *funcs;
+
+   Debug(LGPFX "Sending: %"FMTSZ"u bytes\n", dataLen);
+
+   ASSERT(chan && chan->funcs);
+
+   g_static_mutex_lock(&chan->outLock);
+
+   funcs = chan->funcs;
+   ASSERT(funcs->send);
+
+   if (result != NULL) {
+      *result = NULL;
+   }
+   if (resultLen != NULL) {
+      *resultLen = 0;
+   }
+
+   ok = funcs->send(chan, data, dataLen, &res, &resLen);
+
+   if (!ok && (funcs->getType(chan) != RPCCHANNEL_TYPE_BKDOOR) &&
+       (funcs->stopRpcOut != NULL)) {
+
+       free(res);
+       res = NULL;
+       resLen = 0;
+
+      /* retry once */
+      Debug(LGPFX "Stop RpcOut channel and try to send again ...\n");
+      funcs->stopRpcOut(chan);
+      if (RpcChannel_Start(chan)) {
+         /* The channel may get switched from vsocket to backdoor */
+         funcs = chan->funcs;
+         ASSERT(funcs->send);
+         ok = funcs->send(chan, data, dataLen, &res, &resLen);
+         goto done;
+      }
+
+      ok = FALSE;
+      goto exit;
+   }
+
+done:
+   if (ok) {
+      Debug(LGPFX "Recved %"FMTSZ"u bytes\n", resLen);
+   }
+
+   if (result != NULL) {
+      *result = res;
+   }
+   if (resultLen != NULL) {
+      *resultLen = resLen;
+   }
+
+exit:
+   g_static_mutex_unlock(&chan->outLock);
+   return ok;
+}
+
+
+/**
+ * Open/close RpcChannel each time for sending a Rpc message, this is a wrapper
+ * for RpcChannel APIs.
+ *
+ * @param[in]  data        request data
+ * @param[in]  dataLen     data length
+ * @param[in]  result      reply, should be freed by calling RpcChannel_Free.
+ * @param[in]  resultLen   reply length
+
+ * @returns    TRUE on success.
+ */
+
+gboolean
+RpcChannel_SendOneRaw(const char *data,
+                      size_t dataLen,
+                      char **result,
+                      size_t *resultLen)
+{
+   RpcChannel *chan;
+   gboolean status;
+
+   status = FALSE;
+
+   chan = RpcChannel_New();
+   if (chan == NULL) {
+      if (result != NULL) {
+         *result = Util_SafeStrdup("RpcChannel: Unable to create "
+                                   "the RpcChannel object");
+         if (resultLen != NULL) {
+            *resultLen = strlen(*result);
+         }
+      }
+      goto sent;
+   } else if (!RpcChannel_Start(chan)) {
+      if (result != NULL) {
+         *result = Util_SafeStrdup("RpcChannel: Unable to open the "
+                                   "communication channel");
+         if (resultLen != NULL) {
+            *resultLen = strlen(*result);
+         }
+      }
+      goto sent;
+   } else if (!RpcChannel_Send(chan, data, dataLen, result, resultLen)) {
+      /* We already have the description of the error */
+      goto sent;
+   }
+
+   status = TRUE;
+
+sent:
+   Debug(LGPFX "Request %s: reqlen=%"FMTSZ"u, replyLen=%"FMTSZ"u\n",
+         status ? "OK" : "FAILED", dataLen, resultLen ? *resultLen : 0);
+   if (chan) {
+      RpcChannel_Stop(chan);
+      RpcChannel_Destroy(chan);
+   }
+
+   return status;
+}
+
+
+/**
+ * Open/close RpcChannel each time for sending a Rpc message, this is a wrapper
+ * for RpcChannel APIs.
+ *
+ * @param[out] reply       reply, should be freed by calling RpcChannel_Free.
+ * @param[out] repLen      reply length
+ * @param[in]  reqFmt      request data
+ * @param[in]  ...         optional arguments depending on reqFmt.
+
+ * @returns    TRUE on success.
+ */
+
+gboolean
+RpcChannel_SendOne(char **reply,
+                   size_t *repLen,
+                   char const *reqFmt,
+                   ...)
+{
+   va_list args;
+   gboolean status;
+   char *request;
+   size_t reqLen = 0;
+
+   status = FALSE;
+
+   /* Format the request string */
+   va_start(args, reqFmt);
+   request = Str_Vasprintf(&reqLen, reqFmt, args);
+   va_end(args);
+
+   /*
+    * If Str_Vasprintf failed, write NULL into the reply if the caller wanted
+    * a reply back.
+    */
+   if (request == NULL) {
+      goto error;
+   }
+
+   /*
+    * If the command doesn't contain a space, add one to the end to maintain
+    * compatibility with old VMXs.
+    *
+    * For a long time, the GuestRpc logic in the VMX was wired to expect a
+    * trailing space in every command, even commands without arguments. That is
+    * no longer true, but we must continue to add a trailing space because we
+    * don't know whether we're talking to an old or new VMX.
+    */
+   if (request[reqLen - 1] != ' ') {
+      char *tmp;
+
+      tmp = Str_Asprintf(NULL, "%s ", request);
+      free(request);
+      request = tmp;
+
+      /*
+       * If Str_Asprintf failed, write NULL into reply if the caller wanted
+       * a reply back.
+       */
+      if (request == NULL) {
+         goto error;
+      }
+   }
+
+   status = RpcChannel_SendOneRaw(request, reqLen, reply, repLen);
+
+   free(request);
+
+   return status;
+
+error:
+   if (reply) {
+      *reply = NULL;
+   }
+
+   if (repLen) {
+      *repLen = 0;
+   }
+   return FALSE;
+}
diff -Naur a/services/vmtoolsd/mainLoop.c b/services/vmtoolsd/mainLoop.c
--- a/services/vmtoolsd/mainLoop.c	2015-11-24 07:59:42.000000000 +0100
+++ b/services/vmtoolsd/mainLoop.c	2016-01-15 11:52:19.332545573 +0100
@@ -384,9 +384,7 @@
    GMainContext *gctx;
    ToolsServiceProperty ctxProp = { TOOLS_CORE_PROP_CTX };
 
-   if (!g_thread_supported()) {
-      g_thread_init(NULL);
-   }
+   g_thread_init(NULL);
 
    /*
     * Useful for debugging purposes. Log the vesion and build information.
diff -Naur a/services/plugins/vmbackup/stateMachine.c b/services/plugins/vmbackup/stateMachine.c
--- a/services/plugins/vmbackup/stateMachine.c	2015-11-24 07:59:42.000000000 +0100
+++ b/services/plugins/vmbackup/stateMachine.c	2016-01-15 11:58:56.387357439 +0100
@@ -279,12 +279,12 @@
       g_source_unref(gBackupState->abortTimer);
    }
 
-   g_static_mutex_lock(&gBackupState->opLock);
+   g_mutex_lock(&gBackupState->opLock);
    if (gBackupState->currentOp != NULL) {
       VmBackup_Cancel(gBackupState->currentOp);
       VmBackup_Release(gBackupState->currentOp);
    }
-   g_static_mutex_unlock(&gBackupState->opLock);
+   g_mutex_unlock(&gBackupState->opLock);
 
    VmBackup_SendEvent(VMBACKUP_EVENT_REQUESTOR_DONE, VMBACKUP_SUCCESS, "");
 
@@ -299,7 +299,7 @@
    }
 
    gBackupState->provider->release(gBackupState->provider);
-   g_static_mutex_free(&gBackupState->opLock);
+   g_mutex_free(&gBackupState->opLock);
    g_free(gBackupState->scriptArg);
    g_free(gBackupState->volumes);
    g_free(gBackupState->snapshots);
@@ -418,13 +418,13 @@
    if (gBackupState->machineState != VMBACKUP_MSTATE_SCRIPT_ERROR &&
        gBackupState->machineState != VMBACKUP_MSTATE_SYNC_ERROR) {
       /* Mark the current operation as cancelled. */
-      g_static_mutex_lock(&gBackupState->opLock);
+      g_mutex_lock(&gBackupState->opLock);
       if (gBackupState->currentOp != NULL) {
          VmBackup_Cancel(gBackupState->currentOp);
          VmBackup_Release(gBackupState->currentOp);
          gBackupState->currentOp = NULL;
       }
-      g_static_mutex_unlock(&gBackupState->opLock);
+      g_mutex_unlock(&gBackupState->opLock);
 
       VmBackup_SendEvent(VMBACKUP_EVENT_REQUESTOR_ABORT,
                          VMBACKUP_REMOTE_ABORT,
@@ -478,32 +478,32 @@
    g_source_unref(gBackupState->timerEvent);
    gBackupState->timerEvent = NULL;
 
-   g_static_mutex_lock(&gBackupState->opLock);
+   g_mutex_lock(&gBackupState->opLock);
    if (gBackupState->currentOp != NULL) {
       g_debug("VmBackupAsyncCallback: checking %s\n", gBackupState->currentOpName);
       status = VmBackup_QueryStatus(gBackupState->currentOp);
    }
-   g_static_mutex_unlock(&gBackupState->opLock);
+   g_mutex_unlock(&gBackupState->opLock);
 
    switch (status) {
    case VMBACKUP_STATUS_PENDING:
       goto exit;
 
    case VMBACKUP_STATUS_FINISHED:
-      g_static_mutex_lock(&gBackupState->opLock);
+      g_mutex_lock(&gBackupState->opLock);
       if (gBackupState->currentOpName != NULL) {
          g_debug("Async request '%s' completed\n", gBackupState->currentOpName);
          VmBackup_Release(gBackupState->currentOp);
          gBackupState->currentOpName = NULL;
       }
       gBackupState->currentOp = NULL;
-      g_static_mutex_unlock(&gBackupState->opLock);
+      g_mutex_unlock(&gBackupState->opLock);
       break;
 
    default:
       {
          gchar *msg;
-         g_static_mutex_lock(&gBackupState->opLock);
+         g_mutex_lock(&gBackupState->opLock);
          if (gBackupState->errorMsg != NULL) {
             msg = g_strdup_printf("'%s' operation failed: %s",
                                   gBackupState->currentOpName,
@@ -519,7 +519,7 @@
 
          VmBackup_Release(gBackupState->currentOp);
          gBackupState->currentOp = NULL;
-         g_static_mutex_unlock(&gBackupState->opLock);
+         g_mutex_unlock(&gBackupState->opLock);
          VmBackupOnError();
          goto exit;
       }
@@ -534,12 +534,12 @@
       gBackupState->callback = NULL;
 
       if (cb(gBackupState)) {
-         g_static_mutex_lock(&gBackupState->opLock);
+         g_mutex_lock(&gBackupState->opLock);
          if (gBackupState->currentOp != NULL || gBackupState->forceRequeue) {
-            g_static_mutex_unlock(&gBackupState->opLock);
+            g_mutex_unlock(&gBackupState->opLock);
             goto exit;
          }
-         g_static_mutex_unlock(&gBackupState->opLock);
+         g_mutex_unlock(&gBackupState->opLock);
       } else {
          VmBackupOnError();
          goto exit;
@@ -823,7 +823,7 @@
    gBackupState->freezeStatus = VMBACKUP_FREEZE_FINISHED;
    gBackupState->provider = provider;
    gBackupState->needsPriv = FALSE;
-   g_static_mutex_init(&gBackupState->opLock);
+   g_mutex_init(&gBackupState->opLock);
    gBackupState->enableNullDriver = VmBackupConfigGetBoolean(ctx->config,
                                                              "enableNullDriver",
                                                              TRUE);
diff -Naur a/services/plugins/vmbackup/vmBackupInt.h b/services/plugins/vmbackup/vmBackupInt.h
--- a/services/plugins/vmbackup/vmBackupInt.h	2015-11-24 07:59:42.000000000 +0100
+++ b/services/plugins/vmbackup/vmBackupInt.h	2016-01-15 11:55:41.944020643 +0100
@@ -98,7 +98,7 @@
    ToolsAppCtx   *ctx;
    VmBackupOp    *currentOp;
    const char    *currentOpName;
-   GStaticMutex   opLock; // See note above
+   GMutex        opLock; // See note above
    char          *volumes;
    char          *snapshots;
    guint          pollPeriod;
@@ -171,14 +171,14 @@
    ASSERT(state->currentOp == NULL);
    ASSERT(currentOpName != NULL);
 
-   g_static_mutex_lock(&state->opLock);
+   g_mutex_lock(&state->opLock);
 
    state->currentOp = op;
    state->callback = callback;
    state->currentOpName = currentOpName;
    state->forceRequeue = (callback != NULL && op == NULL);
 
-   g_static_mutex_unlock(&state->opLock);
+   g_mutex_unlock(&state->opLock);
 
    return (op != NULL);
 }
