darwin: speed up uv_set_process_title()
Libuv loaded and unloaded the Core Services and Application Services for every call to uv_set_process_title(). Change that to load them on the first call to uv_set_process_title() and delay unloading until libuv is unloaded. Speeds up process_title_threadsafe by about 10x on my system. It should fail less often (hopefully not at all) on the CI now. PR-URL: https://github.com/libuv/libuv/pull/2480 Reviewed-By: Saúl Ibarra Corretgé <s@saghul.net>
This commit is contained in:
parent
e83dba7f93
commit
038eacfbf4
@ -33,61 +33,57 @@
|
|||||||
# include <ApplicationServices/ApplicationServices.h>
|
# include <ApplicationServices/ApplicationServices.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define S(s) pCFStringCreateWithCString(NULL, (s), kCFStringEncodingUTF8)
|
||||||
|
|
||||||
static int uv__pthread_setname_np(const char* name) {
|
|
||||||
int (*dynamic_pthread_setname_np)(const char* name);
|
static int (*dynamic_pthread_setname_np)(const char* name);
|
||||||
char namebuf[64]; /* MAXTHREADNAMESIZE */
|
#if !TARGET_OS_IPHONE
|
||||||
int err;
|
static CFStringRef (*pCFStringCreateWithCString)(CFAllocatorRef,
|
||||||
|
const char*,
|
||||||
|
CFStringEncoding);
|
||||||
|
static CFBundleRef (*pCFBundleGetBundleWithIdentifier)(CFStringRef);
|
||||||
|
static void *(*pCFBundleGetDataPointerForName)(CFBundleRef, CFStringRef);
|
||||||
|
static void *(*pCFBundleGetFunctionPointerForName)(CFBundleRef, CFStringRef);
|
||||||
|
static CFTypeRef (*pLSGetCurrentApplicationASN)(void);
|
||||||
|
static OSStatus (*pLSSetApplicationInformationItem)(int,
|
||||||
|
CFTypeRef,
|
||||||
|
CFStringRef,
|
||||||
|
CFStringRef,
|
||||||
|
CFDictionaryRef*);
|
||||||
|
static void* application_services_handle;
|
||||||
|
static void* core_foundation_handle;
|
||||||
|
static CFBundleRef launch_services_bundle;
|
||||||
|
static CFStringRef* display_name_key;
|
||||||
|
static CFDictionaryRef (*pCFBundleGetInfoDictionary)(CFBundleRef);
|
||||||
|
static CFBundleRef (*pCFBundleGetMainBundle)(void);
|
||||||
|
static CFBundleRef hi_services_bundle;
|
||||||
|
static CFDictionaryRef (*pLSApplicationCheckIn)(int, CFDictionaryRef);
|
||||||
|
static void (*pLSSetApplicationLaunchServicesServerConnectionStatus)(uint64_t,
|
||||||
|
void*);
|
||||||
|
|
||||||
|
|
||||||
|
UV_DESTRUCTOR(static void uv__set_process_title_platform_fini(void)) {
|
||||||
|
if (core_foundation_handle != NULL) {
|
||||||
|
dlclose(core_foundation_handle);
|
||||||
|
core_foundation_handle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (application_services_handle != NULL) {
|
||||||
|
dlclose(application_services_handle);
|
||||||
|
application_services_handle = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* !TARGET_OS_IPHONE */
|
||||||
|
|
||||||
|
|
||||||
|
void uv__set_process_title_platform_init(void) {
|
||||||
|
OSStatus (*pSetApplicationIsDaemon)(int);
|
||||||
|
|
||||||
/* pthread_setname_np() first appeared in OS X 10.6 and iOS 3.2. */
|
/* pthread_setname_np() first appeared in OS X 10.6 and iOS 3.2. */
|
||||||
*(void **)(&dynamic_pthread_setname_np) =
|
*(void **)(&dynamic_pthread_setname_np) =
|
||||||
dlsym(RTLD_DEFAULT, "pthread_setname_np");
|
dlsym(RTLD_DEFAULT, "pthread_setname_np");
|
||||||
|
|
||||||
if (dynamic_pthread_setname_np == NULL)
|
#if !TARGET_OS_IPHONE
|
||||||
return UV_ENOSYS;
|
|
||||||
|
|
||||||
strncpy(namebuf, name, sizeof(namebuf) - 1);
|
|
||||||
namebuf[sizeof(namebuf) - 1] = '\0';
|
|
||||||
|
|
||||||
err = dynamic_pthread_setname_np(namebuf);
|
|
||||||
if (err)
|
|
||||||
return UV__ERR(err);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int uv__set_process_title(const char* title) {
|
|
||||||
#if TARGET_OS_IPHONE
|
|
||||||
return uv__pthread_setname_np(title);
|
|
||||||
#else
|
|
||||||
CFStringRef (*pCFStringCreateWithCString)(CFAllocatorRef,
|
|
||||||
const char*,
|
|
||||||
CFStringEncoding);
|
|
||||||
CFBundleRef (*pCFBundleGetBundleWithIdentifier)(CFStringRef);
|
|
||||||
void *(*pCFBundleGetDataPointerForName)(CFBundleRef, CFStringRef);
|
|
||||||
void *(*pCFBundleGetFunctionPointerForName)(CFBundleRef, CFStringRef);
|
|
||||||
CFTypeRef (*pLSGetCurrentApplicationASN)(void);
|
|
||||||
OSStatus (*pLSSetApplicationInformationItem)(int,
|
|
||||||
CFTypeRef,
|
|
||||||
CFStringRef,
|
|
||||||
CFStringRef,
|
|
||||||
CFDictionaryRef*);
|
|
||||||
void* application_services_handle;
|
|
||||||
void* core_foundation_handle;
|
|
||||||
CFBundleRef launch_services_bundle;
|
|
||||||
CFStringRef* display_name_key;
|
|
||||||
CFDictionaryRef (*pCFBundleGetInfoDictionary)(CFBundleRef);
|
|
||||||
CFBundleRef (*pCFBundleGetMainBundle)(void);
|
|
||||||
CFBundleRef hi_services_bundle;
|
|
||||||
OSStatus (*pSetApplicationIsDaemon)(int);
|
|
||||||
CFDictionaryRef (*pLSApplicationCheckIn)(int, CFDictionaryRef);
|
|
||||||
void (*pLSSetApplicationLaunchServicesServerConnectionStatus)(uint64_t,
|
|
||||||
void*);
|
|
||||||
CFTypeRef asn;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
err = UV_ENOENT;
|
|
||||||
application_services_handle = dlopen("/System/Library/Frameworks/"
|
application_services_handle = dlopen("/System/Library/Frameworks/"
|
||||||
"ApplicationServices.framework/"
|
"ApplicationServices.framework/"
|
||||||
"Versions/A/ApplicationServices",
|
"Versions/A/ApplicationServices",
|
||||||
@ -116,8 +112,6 @@ int uv__set_process_title(const char* title) {
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define S(s) pCFStringCreateWithCString(NULL, (s), kCFStringEncodingUTF8)
|
|
||||||
|
|
||||||
launch_services_bundle =
|
launch_services_bundle =
|
||||||
pCFBundleGetBundleWithIdentifier(S("com.apple.LaunchServices"));
|
pCFBundleGetBundleWithIdentifier(S("com.apple.LaunchServices"));
|
||||||
|
|
||||||
@ -148,13 +142,14 @@ int uv__set_process_title(const char* title) {
|
|||||||
"CFBundleGetInfoDictionary");
|
"CFBundleGetInfoDictionary");
|
||||||
*(void **)(&pCFBundleGetMainBundle) = dlsym(core_foundation_handle,
|
*(void **)(&pCFBundleGetMainBundle) = dlsym(core_foundation_handle,
|
||||||
"CFBundleGetMainBundle");
|
"CFBundleGetMainBundle");
|
||||||
|
|
||||||
if (pCFBundleGetInfoDictionary == NULL || pCFBundleGetMainBundle == NULL)
|
if (pCFBundleGetInfoDictionary == NULL || pCFBundleGetMainBundle == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* Black 10.9 magic, to remove (Not responding) mark in Activity Monitor */
|
/* Black 10.9 magic, to remove (Not responding) mark in Activity Monitor */
|
||||||
hi_services_bundle =
|
hi_services_bundle =
|
||||||
pCFBundleGetBundleWithIdentifier(S("com.apple.HIServices"));
|
pCFBundleGetBundleWithIdentifier(S("com.apple.HIServices"));
|
||||||
err = UV_ENOENT;
|
|
||||||
if (hi_services_bundle == NULL)
|
if (hi_services_bundle == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@ -168,42 +163,39 @@ int uv__set_process_title(const char* title) {
|
|||||||
pCFBundleGetFunctionPointerForName(
|
pCFBundleGetFunctionPointerForName(
|
||||||
launch_services_bundle,
|
launch_services_bundle,
|
||||||
S("_LSSetApplicationLaunchServicesServerConnectionStatus"));
|
S("_LSSetApplicationLaunchServicesServerConnectionStatus"));
|
||||||
|
|
||||||
if (pSetApplicationIsDaemon == NULL ||
|
if (pSetApplicationIsDaemon == NULL ||
|
||||||
pLSApplicationCheckIn == NULL ||
|
pLSApplicationCheckIn == NULL ||
|
||||||
pLSSetApplicationLaunchServicesServerConnectionStatus == NULL) {
|
pLSSetApplicationLaunchServicesServerConnectionStatus == NULL) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pSetApplicationIsDaemon(1) != noErr)
|
/* Prevent crash when LaunchServices cannot be connected to. */
|
||||||
goto out;
|
pSetApplicationIsDaemon(1);
|
||||||
|
return;
|
||||||
pLSSetApplicationLaunchServicesServerConnectionStatus(0, NULL);
|
|
||||||
|
|
||||||
/* Check into process manager?! */
|
|
||||||
pLSApplicationCheckIn(-2,
|
|
||||||
pCFBundleGetInfoDictionary(pCFBundleGetMainBundle()));
|
|
||||||
|
|
||||||
asn = pLSGetCurrentApplicationASN();
|
|
||||||
|
|
||||||
err = UV_EINVAL;
|
|
||||||
if (pLSSetApplicationInformationItem(-2, /* Magic value. */
|
|
||||||
asn,
|
|
||||||
*display_name_key,
|
|
||||||
S(title),
|
|
||||||
NULL) != noErr) {
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
uv__pthread_setname_np(title); /* Don't care if it fails. */
|
|
||||||
err = 0;
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (core_foundation_handle != NULL)
|
uv__set_process_title_platform_fini();
|
||||||
dlclose(core_foundation_handle);
|
|
||||||
|
|
||||||
if (application_services_handle != NULL)
|
|
||||||
dlclose(application_services_handle);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
#endif /* !TARGET_OS_IPHONE */
|
#endif /* !TARGET_OS_IPHONE */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void uv__set_process_title(const char* title) {
|
||||||
|
#if !TARGET_OS_IPHONE
|
||||||
|
if (core_foundation_handle != NULL) {
|
||||||
|
CFTypeRef asn;
|
||||||
|
pLSSetApplicationLaunchServicesServerConnectionStatus(0, NULL);
|
||||||
|
pLSApplicationCheckIn(/* Magic value */ -2,
|
||||||
|
pCFBundleGetInfoDictionary(pCFBundleGetMainBundle()));
|
||||||
|
asn = pLSGetCurrentApplicationASN();
|
||||||
|
pLSSetApplicationInformationItem(/* Magic value */ -2, asn,
|
||||||
|
*display_name_key, S(title), NULL);
|
||||||
|
}
|
||||||
|
#endif /* !TARGET_OS_IPHONE */
|
||||||
|
|
||||||
|
if (dynamic_pthread_setname_np != NULL) {
|
||||||
|
char namebuf[64]; /* MAXTHREADNAMESIZE */
|
||||||
|
uv__strscpy(namebuf, title, sizeof(namebuf));
|
||||||
|
dynamic_pthread_setname_np(namebuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -24,6 +24,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
extern void uv__set_process_title_platform_init(void);
|
||||||
extern void uv__set_process_title(const char* title);
|
extern void uv__set_process_title(const char* title);
|
||||||
|
|
||||||
static uv_mutex_t process_title_mutex;
|
static uv_mutex_t process_title_mutex;
|
||||||
@ -38,6 +39,9 @@ static struct {
|
|||||||
|
|
||||||
static void init_process_title_mutex_once(void) {
|
static void init_process_title_mutex_once(void) {
|
||||||
uv_mutex_init(&process_title_mutex);
|
uv_mutex_init(&process_title_mutex);
|
||||||
|
#ifdef __APPLE__
|
||||||
|
uv__set_process_title_platform_init();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -25,11 +25,7 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#define NUM_ITERATIONS 50
|
||||||
# define NUM_ITERATIONS 10
|
|
||||||
#else
|
|
||||||
# define NUM_ITERATIONS 50
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const char* titles[] = {
|
static const char* titles[] = {
|
||||||
"8L2NY0Kdj0XyNFZnmUZigIOfcWjyNr0SkMmUhKw99VLUsZFrvCQQC3XIRfNR8pjyMjXObllled",
|
"8L2NY0Kdj0XyNFZnmUZigIOfcWjyNr0SkMmUhKw99VLUsZFrvCQQC3XIRfNR8pjyMjXObllled",
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user