VirtualBox

source: vbox/trunk/src/VBox/Main/include/ClientWatcher.h@ 64613

Last change on this file since 64613 was 60066, checked in by vboxsync, 9 years ago

ClientWatcher: Moved the process reaping code into a separate method, stopping the tratition of duplicating the code exactly for each platform. Make Windows and OS/2 call it too, adjusting the windows loop to only wait 5 seconds after session close to reduce the chance of dead child hanging around for a long time. (Not reaping processes on windows had the consequence of potentially leaking one process handle with associated kernel object, and have an ever growing process handle table in IPRT.)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.4 KB
Line 
1/* $Id: ClientWatcher.h 60066 2016-03-16 18:28:40Z vboxsync $ */
2/** @file
3 * VirtualBox API client session watcher
4 */
5
6/*
7 * Copyright (C) 2013-2016 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef ____H_CLIENTWATCHER
19#define ____H_CLIENTWATCHER
20
21
22#include <list>
23#include <VBox/com/ptr.h>
24#include <VBox/com/AutoLock.h>
25
26#include "VirtualBoxImpl.h"
27
28#if defined(RT_OS_WINDOWS)
29# define CWUPDATEREQARG NULL
30# define CWUPDATEREQTYPE HANDLE
31# define CW_MAX_CLIENTS _16K /**< Max number of clients we can watch (windows). */
32# ifndef DEBUG /* The debug version triggers worker thread code much much earlier. */
33# define CW_MAX_CLIENTS_PER_THREAD 63 /**< Max clients per watcher thread (windows). */
34# else
35# define CW_MAX_CLIENTS_PER_THREAD 3 /**< Max clients per watcher thread (windows). */
36# endif
37# define CW_MAX_HANDLES_PER_THREAD (CW_MAX_CLIENTS_PER_THREAD + 1) /**< Max handles per thread. */
38
39#elif defined(RT_OS_OS2)
40# define CWUPDATEREQARG NIL_RTSEMEVENT
41# define CWUPDATEREQTYPE RTSEMEVENT
42
43#elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER) || defined(VBOX_WITH_GENERIC_SESSION_WATCHER)
44# define CWUPDATEREQARG NIL_RTSEMEVENT
45# define CWUPDATEREQTYPE RTSEMEVENT
46
47#else
48# error "Port me!"
49#endif
50
51/**
52 * Class which checks for API clients which have crashed/exited, and takes
53 * the necessary cleanup actions. Singleton.
54 */
55class VirtualBox::ClientWatcher
56{
57public:
58 /**
59 * Constructor which creates a usable instance
60 *
61 * @param pVirtualBox Reference to VirtualBox object
62 */
63 ClientWatcher(const ComObjPtr<VirtualBox> &pVirtualBox);
64
65 /**
66 * Default destructor. Cleans everything up.
67 */
68 ~ClientWatcher();
69
70 bool isReady();
71
72 void update();
73 void addProcess(RTPROCESS pid);
74
75private:
76 /**
77 * Default constructor. Don't use, will not create a sensible instance.
78 */
79 ClientWatcher();
80
81 static DECLCALLBACK(int) worker(RTTHREAD hThreadSelf, void *pvUser);
82 uint32_t reapProcesses(void);
83
84 VirtualBox *mVirtualBox;
85 RTTHREAD mThread;
86 CWUPDATEREQTYPE mUpdateReq;
87 util::RWLockHandle mLock;
88
89 typedef std::list<RTPROCESS> ProcessList;
90 ProcessList mProcesses;
91
92#if defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER) || defined(VBOX_WITH_GENERIC_SESSION_WATCHER)
93 uint8_t mUpdateAdaptCtr;
94#endif
95#ifdef RT_OS_WINDOWS
96 /** Indicate a real update request is pending.
97 * To avoid race conditions this must be set before mUpdateReq is signalled and
98 * read after resetting mUpdateReq. */
99 volatile bool mfUpdateReq;
100 /** Set when the worker threads are supposed to shut down. */
101 volatile bool mfTerminate;
102 /** Number of active subworkers.
103 * When decremented to 0, subworker zero is signalled. */
104 uint32_t volatile mcActiveSubworkers;
105 /** Number of valid handles in mahWaitHandles. */
106 uint32_t mcWaitHandles;
107 /** The wait interval (usually INFINITE). */
108 uint32_t mcMsWait;
109 /** Per subworker data. Subworker 0 is the main worker and does not have a
110 * pReq pointer since. */
111 struct PerSubworker
112 {
113 /** The wait result. */
114 DWORD dwWait;
115 /** The subworker index. */
116 uint32_t iSubworker;
117 /** The subworker thread handle. */
118 RTTHREAD hThread;
119 /** Self pointer (for worker thread). */
120 VirtualBox::ClientWatcher *pSelf;
121 } maSubworkers[(CW_MAX_CLIENTS + CW_MAX_CLIENTS_PER_THREAD - 1) / CW_MAX_CLIENTS_PER_THREAD];
122 /** Wait handle array. The mUpdateReq manual reset event handle is inserted
123 * every 64 entries, first entry being 0. */
124 HANDLE mahWaitHandles[CW_MAX_CLIENTS + (CW_MAX_CLIENTS + CW_MAX_CLIENTS_PER_THREAD - 1) / CW_MAX_CLIENTS_PER_THREAD];
125
126 void subworkerWait(VirtualBox::ClientWatcher::PerSubworker *pSubworker, uint32_t cMsWait);
127 static DECLCALLBACK(int) subworkerThread(RTTHREAD hThreadSelf, void *pvUser);
128 void winResetHandleArray(uint32_t cProcHandles);
129#endif
130};
131
132#endif /* !____H_CLIENTWATCHER */
133/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette