static void RpcInCloseChannel(RpcIn *in, // IN char const *errmsg) // IN { /* Call the error routine */ (*in->errorFunc)(in->errorData, errmsg); RpcInStop(in); in->shouldStop = FALSE; }
void RpcIn_stop(RpcIn *in) // IN { if (in->inLoop) { in->shouldStop = TRUE; } else { RpcInStop(in); } }
static void RpcInShutdown(RpcChannel *chan) { BackdoorChannel *bdoor = chan->_private; RpcInStop(chan); if (bdoor->in != NULL) { RpcIn_Destruct(bdoor->in); } RpcOut_Destruct(bdoor->out); g_static_mutex_free(&bdoor->outLock); if (bdoor->mainCtx != NULL) { g_main_context_unref(bdoor->mainCtx); } g_free(bdoor); }
static Bool RpcInOpenChannel(RpcIn *in, // IN Bool useBackdoorOnly) // IN { #if defined(VMTOOLS_USE_VSOCKET) static Bool first = TRUE; static Bool initOk = TRUE; AsyncSocket *asock; int res; ASSERT(in->conn == NULL); while (TRUE) { /* one pass loop */ if (useBackdoorOnly) { break; } if (first) { first = FALSE; res = AsyncSocket_Init(); initOk = (res == ASOCKERR_SUCCESS); if (!initOk) { Debug("RpcIn: Error in socket initialization: %s\n", AsyncSocket_Err2String(res)); break; } } if (!initOk) { break; } in->conn = calloc(1, sizeof *(in->conn)); if (in->conn == NULL) { Debug("RpcIn: Error in allocating memory for vsocket connection.\n"); break; } in->conn->in = in; asock = AsyncSocket_ConnectVMCI(VMCI_HYPERVISOR_CONTEXT_ID, GUESTRPC_TCLO_VSOCK_LISTEN_PORT, RpcInConnectDone, in->conn, 0, NULL, &res); if (asock == NULL) { Debug("RpcIn: Error in creating vsocket connection: %s\n", AsyncSocket_Err2String(res)); } else { res = AsyncSocket_SetErrorFn(asock, RpcInConnErrorHandler, in->conn); if (res != ASOCKERR_SUCCESS) { Debug("RpcIn: Error in setting error handler for vsocket %d\n", AsyncSocket_GetFd(asock)); AsyncSocket_Close(asock); } else { Debug("RpcIn: successfully created vsocket connection %d.\n", AsyncSocket_GetFd(asock)); in->conn->asock = asock; return TRUE; } } break; } if (in->conn != NULL) { free(in->conn); in->conn = NULL; } #endif ASSERT(in->channel == NULL); in->channel = Message_Open(0x4f4c4354); if (in->channel == NULL) { Debug("RpcIn: couldn't open channel with TCLO protocol\n"); goto error; } if (!RpcInScheduleRecvEvent(in)) { Debug("RpcIn_start: couldn't start the loop\n"); goto error; } in->mustSend = TRUE; return TRUE; error: RpcInStop(in); return FALSE; }
static gboolean #else static Bool #endif RpcInLoop(void *clientData) // IN { RpcIn *in; char const *errmsg = NULL; char const *reply; size_t repLen; Bool resched = FALSE; #if defined(VMTOOLS_USE_GLIB) unsigned int current; #endif in = (RpcIn *)clientData; ASSERT(in); ASSERT(in->nextEvent); ASSERT(in->channel); ASSERT(in->mustSend); #if defined(VMTOOLS_USE_GLIB) current = in->delay; #else /* * The event has fired: it is no longer valid. Note that this is * not true in the glib case! */ in->nextEvent = NULL; #endif in->inLoop = TRUE; /* * Workaround for bug 780404. Remove if we ever figure out the root cause. * Note that the ASSERT above catches this on non-release builds. */ if (in->channel == NULL) { errmsg = "RpcIn: Channel is not active"; goto error; } /* * This is very important: this is the only way to signal the existence of * this guest application to VMware. */ if (RpcInSend(in, 0) == FALSE) { errmsg = "RpcIn: Unable to send"; goto error; } if (Message_Receive(in->channel, (unsigned char **)&reply, &repLen) == FALSE) { errmsg = "RpcIn: Unable to receive"; goto error; } if (repLen) { if (!RpcInExecRpc(in, reply, repLen, &errmsg)) { goto error; } } else { /* * Nothing to execute */ /* No request -> No result */ ASSERT(in->last_result == NULL); ASSERT(in->last_resultLen == 0); RpcInUpdateDelayTime(in); } ASSERT(in->mustSend == FALSE); in->mustSend = TRUE; if (!in->shouldStop) { Bool needResched = TRUE; #if defined(VMTOOLS_USE_GLIB) resched = in->delay != current; needResched = resched; #endif if (needResched && !RpcInScheduleRecvEvent(in)) { errmsg = "RpcIn: Unable to run the loop"; goto error; } } exit: if (in->shouldStop) { RpcInStop(in); in->shouldStop = FALSE; #if defined(VMTOOLS_USE_GLIB) /* Force the GMainContext to unref the GSource that runs the RpcIn loop. */ resched = TRUE; #endif } in->inLoop = FALSE; return !resched; error: /* Call the error routine */ (*in->errorFunc)(in->errorData, errmsg); in->shouldStop = TRUE; goto exit; }