Changeset 29438 in vbox
- Timestamp:
- May 12, 2010 9:50:16 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/HostServices/GuestControlSvc.h
r28887 r29438 136 136 * or starting a program. 137 137 */ 138 HOST_EXEC_CMD = 1 ,138 HOST_EXEC_CMD = 100, 139 139 /** 140 140 * Sends input data for stdin to a running process executed by HOST_EXEC_CMD. 141 141 */ 142 HOST_EXEC_SET_INPUT = 2,142 HOST_EXEC_SET_INPUT = 101, 143 143 /** 144 144 * Gets the current status of a running process, e.g. 145 145 * new data on stdout/stderr, process terminated etc. 146 146 */ 147 HOST_EXEC_GET_OUTPUT = 3147 HOST_EXEC_GET_OUTPUT = 102 148 148 }; 149 149 … … 155 155 { 156 156 /** 157 * Guest waits for a new message the host wants to process on the guest side. 158 * This is a blocking call and can be deferred. 159 */ 160 GUEST_GET_HOST_MSG = 1, 161 /** 162 * Guest asks the host to cancel all pending waits the guest waits on. 163 * This becomes necessary when the guest wants to quit but still waits for 164 * commands from the host. 165 */ 166 GUEST_CANCEL_PENDING_WAITS = 2, 167 /** 157 168 * TODO 158 169 */ 159 GUEST_ GET_HOST_MSG = 1,170 GUEST_EXEC_SEND_OUTPUT = 100, 160 171 /** 161 172 * TODO 162 173 */ 163 GUEST_EXEC_SEND_OUTPUT = 2, 164 /** 165 * TODO 166 */ 167 GUEST_EXEC_SEND_STATUS = 3 174 GUEST_EXEC_SEND_STATUS = 101 168 175 }; 169 176 … … 175 182 { 176 183 /** 184 * Hosts wants the guest to stop waiting for new messages. 185 */ 186 GETHOSTMSG_EXEC_HOST_CANCEL_WAIT = 0, 187 /** 177 188 * The host wants to execute something in the guest. This can be a command line 178 189 * or starting a program. 179 190 */ 180 GETHOSTMSG_EXEC_START_PROCESS = 1 ,191 GETHOSTMSG_EXEC_START_PROCESS = 100, 181 192 /** 182 193 * Sends input data for stdin to a running process executed by HOST_EXEC_CMD. 183 194 */ 184 GETHOSTMSG_EXEC_SEND_INPUT = 2,195 GETHOSTMSG_EXEC_SEND_INPUT = 101, 185 196 /** 186 197 * Host requests the so far collected stdout/stderr output 187 198 * from a running process executed by HOST_EXEC_CMD. 188 199 */ 189 GETHOSTMSG_EXEC_GET_OUTPUT = 3200 GETHOSTMSG_EXEC_GET_OUTPUT = 102 190 201 }; 191 202 … … 200 211 /** 201 212 * The returned command the host wants to 202 * executeon the guest.213 * run on the guest. 203 214 */ 204 215 HGCMFunctionParameter msg; /* OUT uint32_t */ 205 216 /** Number of parameters the message needs. */ 206 217 HGCMFunctionParameter num_parms; /* OUT uint32_t */ 207 218 208 219 } VBoxGuestCtrlHGCMMsgType; 220 221 typedef struct _VBoxGuestCtrlHGCMMsgCancelPendingWaits 222 { 223 VBoxGuestHGCMCallInfo hdr; 224 } VBoxGuestCtrlHGCMMsgCancelPendingWaits; 209 225 210 226 typedef struct _VBoxGuestCtrlHGCMMsgExecCmd -
trunk/include/VBox/VBoxGuestLib.h
r29307 r29438 509 509 VBGLR3DECL(int) VbglR3GuestCtrlConnect(uint32_t *pu32ClientId); 510 510 VBGLR3DECL(int) VbglR3GuestCtrlDisconnect(uint32_t u32ClientId); 511 VBGLR3DECL(int) VbglR3GuestCtrlGetHostMsg(uint32_t u32ClientId, uint32_t *puMsg, uint32_t *puNumParms, uint32_t u32Timeout); 511 VBGLR3DECL(int) VbglR3GuestCtrlGetHostMsg(uint32_t u32ClientId, uint32_t *puMsg, uint32_t *puNumParms); 512 VBGLR3DECL(int) VbglR3GuestCtrlCancelPendingWaits(uint32_t u32ClientId); 512 513 VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmd(uint32_t u32ClientId, uint32_t uNumParms, 513 514 uint32_t *puContext, -
trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestCtrl.cpp
r28887 r29438 103 103 * in a second call to the host. 104 104 */ 105 VBGLR3DECL(int) VbglR3GuestCtrlGetHostMsg(uint32_t u32ClientId, uint32_t *puMsg, uint32_t *puNumParms , uint32_t u32Timeout)105 VBGLR3DECL(int) VbglR3GuestCtrlGetHostMsg(uint32_t u32ClientId, uint32_t *puMsg, uint32_t *puNumParms) 106 106 { 107 107 AssertPtr(puMsg); … … 127 127 rc = Msg.hdr.result; 128 128 /* Ok, so now we know what message type and how much parameters there are. */ 129 } 130 return rc; 131 } 132 133 134 /** 135 * Asks the host to cancel (release) all pending waits which were deferred. 136 * 137 * @returns VBox status code. 138 * @param u32ClientId The client id returned by VbglR3GuestCtrlConnect(). 139 */ 140 VBGLR3DECL(int) VbglR3GuestCtrlCancelPendingWaits(uint32_t u32ClientId) 141 { 142 VBoxGuestCtrlHGCMMsgCancelPendingWaits Msg; 143 144 Msg.hdr.result = VERR_WRONG_ORDER; 145 Msg.hdr.u32ClientID = u32ClientId; 146 Msg.hdr.u32Function = GUEST_CANCEL_PENDING_WAITS; 147 Msg.hdr.cParms = 0; 148 149 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); 150 if (RT_SUCCESS(rc)) 151 { 152 int rc2 = Msg.hdr.result; 153 if (RT_FAILURE(rc2)) 154 rc = rc2; 129 155 } 130 156 return rc; -
trunk/src/VBox/Additions/common/VBoxService/VBoxService.cpp
r29345 r29438 358 358 VBoxServiceVerbose(1, "Starting '%s' in the main thread\n", g_aServices[iMain].pDesc->pszName); 359 359 rc = g_aServices[iMain].pDesc->pfnWorker(&g_fShutdown); 360 if (rc != VINF_SUCCESS) /* Only complain if service returned an error. Otherwise the service is a one-timer. */ 361 { 362 VBoxServiceError("Service '%s' stopped unexpected; rc=%Rrc\n", g_aServices[iMain].pDesc->pszName, rc); 363 } 360 if (RT_SUCCESS(rc)) 361 VBoxServiceVerbose(1, "Main service '%s' successfully stopped.\n", g_aServices[iMain].pDesc->pszName); 362 else /* Only complain if service returned an error. Otherwise the service is a one-timer. */ 363 VBoxServiceError("Service '%s' stopped unexpected; rc=%Rrc\n", g_aServices[iMain].pDesc->pszName, rc); 364 g_aServices[iMain].pDesc->pfnTerm(); 364 365 } 365 366 return rc; … … 376 377 { 377 378 int rc = VINF_SUCCESS; 379 int iMain = VBoxServiceGetStartedServices(); 378 380 379 381 for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++) … … 381 383 for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++) 382 384 if (g_aServices[j].fStarted) 385 { 386 VBoxServiceVerbose(3, "Calling stop function for service '%s' ...\n", g_aServices[j].pDesc->pszName); 383 387 g_aServices[j].pDesc->pfnStop(); 384 for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++) 385 if (g_aServices[j].fEnabled) 388 } 389 for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++) 390 391 if ( !g_aServices[j].fEnabled /* Only stop services which were started before. */ 392 || j == iMain) /* Don't call the termination function for main service yet. */ 393 { 394 continue; 395 } 396 else 386 397 { 387 398 if (g_aServices[j].Thread != NIL_RTTHREAD) … … 405 416 } 406 417 418 #ifdef RT_OS_WINDOWS 419 /* 420 * As we're now done terminating all service threads, 421 * we have to stop the main thread as well (if defined). Note that the termination 422 * function will be called in a later context (when the main thread returns from the worker 423 * function). 424 */ 425 if (iMain != ~0U) 426 { 427 VBoxServiceVerbose(3, "Stopping main service '%s' (%d) ...\n", g_aServices[iMain].pDesc->pszName, iMain); 428 429 ASMAtomicXchgBool(&g_fShutdown, true); 430 g_aServices[iMain].pDesc->pfnStop(); 431 } 432 #endif 433 407 434 VBoxServiceVerbose(2, "Stopping services returned: rc=%Rrc\n", rc); 408 435 return rc; -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp
r29345 r29438 247 247 uint32_t uNumParms; 248 248 VBoxServiceVerbose(3, "Control: Waiting for host msg ...\n"); 249 rc = VbglR3GuestCtrlGetHostMsg(g_GuestControlSvcClientID, &uMsg, &uNumParms , 1000 /* 1s timeout */);249 rc = VbglR3GuestCtrlGetHostMsg(g_GuestControlSvcClientID, &uMsg, &uNumParms); 250 250 if (RT_FAILURE(rc)) 251 251 { … … 264 264 switch(uMsg) 265 265 { 266 case GETHOSTMSG_EXEC_HOST_CANCEL_WAIT: 267 VBoxServiceVerbose(3, "Control: Host asked us to quit ...\n"); 268 break; 269 266 270 case GETHOSTMSG_EXEC_START_PROCESS: 267 271 rc = VBoxServiceControlHandleCmdStartProcess(g_GuestControlSvcClientID, uNumParms); … … 283 287 284 288 /* Do we need to shutdown? */ 285 if (*pfShutdown) 286 { 287 rc = 0; 289 if ( *pfShutdown 290 || uMsg == GETHOSTMSG_EXEC_HOST_CANCEL_WAIT) 291 { 292 rc = VINF_SUCCESS; 288 293 break; 289 294 } … … 302 307 static DECLCALLBACK(void) VBoxServiceControlStop(void) 303 308 { 309 VBoxServiceVerbose(3, "Control: Stopping ...\n"); 310 304 311 /** @todo Later, figure what to do if we're in RTProcWait(). it's a very 305 312 * annoying call since doesn't support timeouts in the posix world. */ 306 313 RTSemEventMultiSignal(g_hControlEvent); 314 315 /* 316 * Ask the host service to cancel all pending requests so that we can 317 * shutdown properly here. 318 */ 319 if (g_GuestControlSvcClientID) 320 { 321 int rc = VbglR3GuestCtrlCancelPendingWaits(g_GuestControlSvcClientID); 322 if (RT_FAILURE(rc)) 323 VBoxServiceError("Control: Cancelling pending waits failed; rc=%Rrc\n", rc); 324 } 307 325 } 308 326 … … 311 329 static DECLCALLBACK(void) VBoxServiceControlTerm(void) 312 330 { 331 VBoxServiceVerbose(3, "Control: Terminating ...\n"); 332 313 333 /* Signal all threads that we want to shutdown. */ 314 334 PVBOXSERVICECTRLTHREAD pNode; … … 321 341 if (pNode->Thread != NIL_RTTHREAD) 322 342 { 343 /* Wait a bit ... */ 323 344 int rc2 = RTThreadWait(pNode->Thread, 30 * 1000 /* Wait 30 seconds max. */, NULL); 324 345 if (RT_FAILURE(rc2)) -
trunk/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp
r29193 r29438 318 318 if (verbose) 319 319 RTPrintf("No time left to wait for process!\n"); 320 } 320 } 321 321 } 322 322 else if (verbose) 323 RTPrintf("Waiting for process to exit ...\n"); 323 RTPrintf("Waiting for process to exit ...\n"); 324 324 325 325 /* setup signal handling if cancelable */ … … 344 344 while (SUCCEEDED(progress->COMGETTER(Completed(&fCompleted)))) 345 345 { 346 /* 346 /* 347 347 * because we want to get all the output data even if the process 348 348 * already ended, we first need to check whether there is some data 349 349 * left to output before checking the actual timeout and is-process-completed 350 * stuff. 350 * stuff. 351 351 */ 352 352 if (cbOutputData <= 0) … … 363 363 } 364 364 365 if ( waitForStdOut 365 if ( waitForStdOut 366 366 || waitForStdErr) 367 367 { 368 CHECK_ERROR_BREAK(guest, GetProcessOutput(uPID, 0 /* aFlags */, 368 CHECK_ERROR_BREAK(guest, GetProcessOutput(uPID, 0 /* aFlags */, 369 369 u32TimeoutMS, _64K, ComSafeArrayAsOutParam(aOutputData))); 370 370 cbOutputData = aOutputData.size(); … … 421 421 } 422 422 else 423 { 423 { 424 424 if (fCompleted) 425 425 { … … 440 440 CHECK_ERROR_BREAK(guest, GetProcessStatus(uPID, &uRetExitCode, &uRetFlags, &uRetStatus)); 441 441 RTPrintf("Exit code=%u (Status=%u, Flags=%u)\n", uRetExitCode, uRetStatus, uRetFlags); 442 } 443 } 444 else /* not completed yet? -> timeout */ 445 { 446 RTPrintf("Process timed out!\n"); 442 } 447 443 } 448 444 } -
trunk/src/VBox/HostServices/GuestControl/service.cpp
r29220 r29438 220 220 int sendHostCmdToGuest(HostCmd *pCmd, VBOXHGCMCALLHANDLE callHandle, uint32_t cParms, VBOXHGCMSVCPARM paParms[]); 221 221 int retrieveNextHostCmd(uint32_t u32ClientID, VBOXHGCMCALLHANDLE callHandle, uint32_t cParms, VBOXHGCMSVCPARM paParms[]); 222 int cancelPendingWaits(uint32_t u32ClientID); 222 223 int notifyHost(uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[]); 223 224 int processHostCmd(uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[]); … … 443 444 } 444 445 446 int Service::cancelPendingWaits(uint32_t u32ClientID) 447 { 448 int rc = VINF_SUCCESS; 449 CallListIter it = mClientList.begin(); 450 while (it != mClientList.end()) 451 { 452 if (it->mClientID == u32ClientID) 453 { 454 if (it->mNumParms >= 2) 455 { 456 it->mParms[0].setUInt32(GETHOSTMSG_EXEC_HOST_CANCEL_WAIT); /* Message ID */ 457 it->mParms[1].setUInt32(0); /* Required parameters for message */ 458 } 459 if (mpHelpers) 460 mpHelpers->pfnCallComplete(it->mHandle, rc); 461 it = mClientList.erase(it); 462 } 463 else 464 it++; 465 } 466 return rc; 467 } 468 445 469 int Service::notifyHost(uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) 446 470 { … … 503 527 504 528 /* In any case the client did something, so wake up and remove from list. */ 529 AssertPtr(mpHelpers); 505 530 mpHelpers->pfnCallComplete(guest.mHandle, rc); 506 531 mClientList.pop_front(); … … 559 584 break; 560 585 586 case GUEST_CANCEL_PENDING_WAITS: 587 LogFlowFunc(("GUEST_CANCEL_PENDING_WAITS\n")); 588 rc = cancelPendingWaits(u32ClientID); 589 break; 590 561 591 /* The guest notifies the host that some output at stdout/stderr is available. */ 562 592 case GUEST_EXEC_SEND_OUTPUT: … … 578 608 { 579 609 /* Tell the client that the call is complete (unblocks waiting). */ 610 AssertPtr(mpHelpers); 580 611 mpHelpers->pfnCallComplete(callHandle, rc); 581 612 }
Note:
See TracChangeset
for help on using the changeset viewer.