mirror of https://github.com/BOINC/boinc.git
client: Revise Apple idle time detection for compatibility with OS 10.6
svn path=/trunk/boinc/; revision=17432
This commit is contained in:
parent
66ec889431
commit
2a18a8abeb
|
@ -2506,3 +2506,11 @@ David 2 Mar 2009
|
|||
sched/
|
||||
sched_config.cpp,h
|
||||
sched_locality.cpp
|
||||
|
||||
Charlie 2 Mar 2009
|
||||
- client: Revise Apple idle time detection for compatibility with OS 10.6.
|
||||
|
||||
client/
|
||||
hostinfo_unix.cpp
|
||||
lib/
|
||||
hostinfo.h
|
||||
|
|
|
@ -125,7 +125,8 @@ extern "C" {
|
|||
} // extern "C"
|
||||
#endif
|
||||
|
||||
NXEventHandle gEventHandle = NULL;
|
||||
mach_port_t gEventHandle = NULL;
|
||||
#include "util.h"
|
||||
#endif // __APPLE__
|
||||
|
||||
#ifdef _HPUX_SOURCE
|
||||
|
@ -1078,20 +1079,86 @@ inline bool user_idle(time_t t, struct utmp* u) {
|
|||
|
||||
#ifdef __APPLE__
|
||||
|
||||
// NXIdleTime() is an undocumented Apple API to return user idle time, which
|
||||
// was implemented from before OS 10.0 through OS 10.5. In OS 10.4, Apple
|
||||
// added the CGEventSourceSecondsSinceLastEventType() API as a replacement for
|
||||
// NXIdleTime(). However, BOINC could not use this newer API when configured
|
||||
// as a pre-login launchd daemon unless that daemon was running as root,
|
||||
// because it could not connect to the Window Server. So BOINC continued to
|
||||
// use NXIdleTime().
|
||||
//
|
||||
// In OS 10.6, Apple removed the NXIdleTime() API. BOINC can instead use the
|
||||
// IOHIDGetParameter() API in OS 10.6. When BOINC is a pre-login launchd
|
||||
// daemon running as user boinc_master, this API works properly under OS 10.6
|
||||
// but fails under OS 10.5 and earlier.
|
||||
//
|
||||
// So we use weak-linking of NxIdleTime() to prevent a run-time crash from the
|
||||
// dynamic linker, and use the IOHIDGetParameter() API if NXIdleTime does not
|
||||
// exist.
|
||||
//
|
||||
bool HOST_INFO::users_idle(
|
||||
bool check_all_logins, double idle_time_to_run, double *actual_idle_time
|
||||
) {
|
||||
double idleTime = 0;
|
||||
|
||||
if (gEventHandle) {
|
||||
idleTime = NXIdleTime(gEventHandle);
|
||||
} else {
|
||||
// Initialize Mac OS X idle time measurement / idle detection
|
||||
// Do this here because NXOpenEventStatus() may not be available
|
||||
// immediately on system startup when running as a deaemon.
|
||||
gEventHandle = NXOpenEventStatus();
|
||||
}
|
||||
static double init_time = 0;
|
||||
static bool error_posted = false;
|
||||
double idleTime = 0;
|
||||
io_service_t service;
|
||||
kern_return_t kernResult;
|
||||
UInt64 params;
|
||||
IOByteCount rcnt = sizeof(UInt64);
|
||||
|
||||
if (init_time == 0) init_time = dtime();
|
||||
|
||||
if (NXIdleTime) { // Use NXIdleTime API in OS 10.5 and earlier
|
||||
if (gEventHandle) {
|
||||
idleTime = NXIdleTime(gEventHandle);
|
||||
} else {
|
||||
// Initialize Mac OS X idle time measurement / idle detection
|
||||
// Do this here because NXOpenEventStatus() may not be available
|
||||
// immediately on system startup when running as a deaemon.
|
||||
if ((dtime() - init_time) > 180) { // Limit retries to 180 seconds
|
||||
|
||||
msg_printf(NULL, MSG_USER_ERROR,
|
||||
"User idle detection is disabled: initialization failed."
|
||||
);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
gEventHandle = NXOpenEventStatus();
|
||||
}
|
||||
} else { // NXIdleTime API does not exist in OS 10.6 and later
|
||||
if (gEventHandle) {
|
||||
kernResult = IOHIDGetParameter( gEventHandle, CFSTR(EVSIOIDLE), sizeof(UInt64), ¶ms, &rcnt );
|
||||
if ( kernResult != kIOReturnSuccess ) {
|
||||
if (!error_posted) {
|
||||
msg_printf(NULL, MSG_USER_ERROR,
|
||||
"User idle time measurement failed because IOHIDGetParameter failed."
|
||||
);
|
||||
error_posted = true;
|
||||
}
|
||||
goto bail;
|
||||
}
|
||||
idleTime = ((double)params) / 1000.0 / 1000.0 / 1000.0;
|
||||
} else {
|
||||
// When the system first starts up, allow time for HIDSystem to be available if needed
|
||||
if ((dtime() - init_time) > 180) { // Limit retries to 180 seconds
|
||||
|
||||
msg_printf(NULL, MSG_USER_ERROR,
|
||||
"Could not connect to HIDSystem: user idle detection is disabled."
|
||||
);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching(kIOHIDSystemClass));
|
||||
if (service == 0) goto bail;
|
||||
|
||||
kernResult = IOServiceOpen(service, mach_task_self(), kIOHIDParamConnectType, &gEventHandle);
|
||||
if (kernResult != KERN_SUCCESS) goto bail;
|
||||
|
||||
} // End gEventHandle == NULL
|
||||
} // End NXIdleTime API does not exist
|
||||
|
||||
bail:
|
||||
if (actual_idle_time) {
|
||||
*actual_idle_time = idleTime;
|
||||
}
|
||||
|
|
|
@ -82,9 +82,16 @@ public:
|
|||
extern "C" {
|
||||
#endif
|
||||
#include <mach/port.h>
|
||||
#include <IOKit/hidsystem/IOHIDLib.h>
|
||||
#include <IOKit/hidsystem/IOHIDParameter.h>
|
||||
|
||||
// Apple has removed NxIdleTime() beginning with OS 10.6, so we must use
|
||||
// weak linking to avoid a run-time crash. For details, please see the
|
||||
// comments in the __APPLE__ version of HOST_INFO::users_idle() in
|
||||
// client/hostinfo_unix.cpp.
|
||||
typedef mach_port_t NXEventHandle;
|
||||
NXEventHandle NXOpenEventStatus(void);
|
||||
extern double NXIdleTime(NXEventHandle handle);
|
||||
NXEventHandle NXOpenEventStatus(void) __attribute__((weak_import));
|
||||
extern double NXIdleTime(NXEventHandle handle) __attribute__((weak_import));
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue