Skip to content

Commit

Permalink
Revert "darwin: speed up uv_set_process_title()"
Browse files Browse the repository at this point in the history
This reverts commit 00c6b16.

It's been reported (and I can confirm) that this change breaks
`process.title = 'foo'` in Node.js.

Since libuv just calls out to Core Services and Application Services,
and since those frameworks are really just black boxes that you can't
look inside, it's impossible to debug what exactly goes wrong. Revert
it is then.

Fixes: nodejs/node#28945
  • Loading branch information
bnoordhuis committed Aug 3, 2019
1 parent 2480b61 commit a49bbfd
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 73 deletions.
147 changes: 79 additions & 68 deletions src/unix/darwin-proctitle.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,56 +33,61 @@
# include <ApplicationServices/ApplicationServices.h>
#endif

#define S(s) pCFStringCreateWithCString(NULL, (s), kCFStringEncodingUTF8)


static int (*dynamic_pthread_setname_np)(const char* name);
#if !TARGET_OS_IPHONE
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 OSStatus (*pSetApplicationIsDaemon)(int);
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 */

static int uv__pthread_setname_np(const char* name) {
int (*dynamic_pthread_setname_np)(const char* name);
char namebuf[64]; /* MAXTHREADNAMESIZE */
int err;

void uv__set_process_title_platform_init(void) {
/* pthread_setname_np() first appeared in OS X 10.6 and iOS 3.2. */
*(void **)(&dynamic_pthread_setname_np) =
dlsym(RTLD_DEFAULT, "pthread_setname_np");

#if !TARGET_OS_IPHONE
if (dynamic_pthread_setname_np == NULL)
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/"
"ApplicationServices.framework/"
"Versions/A/ApplicationServices",
Expand Down Expand Up @@ -111,6 +116,8 @@ void uv__set_process_title_platform_init(void) {
goto out;
}

#define S(s) pCFStringCreateWithCString(NULL, (s), kCFStringEncodingUTF8)

launch_services_bundle =
pCFBundleGetBundleWithIdentifier(S("com.apple.LaunchServices"));

Expand Down Expand Up @@ -141,14 +148,13 @@ void uv__set_process_title_platform_init(void) {
"CFBundleGetInfoDictionary");
*(void **)(&pCFBundleGetMainBundle) = dlsym(core_foundation_handle,
"CFBundleGetMainBundle");

if (pCFBundleGetInfoDictionary == NULL || pCFBundleGetMainBundle == NULL)
goto out;

/* Black 10.9 magic, to remove (Not responding) mark in Activity Monitor */
hi_services_bundle =
pCFBundleGetBundleWithIdentifier(S("com.apple.HIServices"));

err = UV_ENOENT;
if (hi_services_bundle == NULL)
goto out;

Expand All @@ -162,37 +168,42 @@ void uv__set_process_title_platform_init(void) {
pCFBundleGetFunctionPointerForName(
launch_services_bundle,
S("_LSSetApplicationLaunchServicesServerConnectionStatus"));

if (pSetApplicationIsDaemon == NULL ||
pLSApplicationCheckIn == NULL ||
pLSSetApplicationLaunchServicesServerConnectionStatus == NULL) {
goto out;
}

return;
if (pSetApplicationIsDaemon(1) != noErr)
goto out;

out:
uv__set_process_title_platform_fini();
#endif /* !TARGET_OS_IPHONE */
}
pLSSetApplicationLaunchServicesServerConnectionStatus(0, NULL);

/* Check into process manager?! */
pLSApplicationCheckIn(-2,
pCFBundleGetInfoDictionary(pCFBundleGetMainBundle()));

void uv__set_process_title(const char* title) {
#if !TARGET_OS_IPHONE
if (core_foundation_handle != NULL && pSetApplicationIsDaemon(1) != noErr) {
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 */
asn = pLSGetCurrentApplicationASN();

if (dynamic_pthread_setname_np != NULL) {
char namebuf[64]; /* MAXTHREADNAMESIZE */
uv__strscpy(namebuf, title, sizeof(namebuf));
dynamic_pthread_setname_np(namebuf);
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:
if (core_foundation_handle != NULL)
dlclose(core_foundation_handle);

if (application_services_handle != NULL)
dlclose(application_services_handle);

return err;
#endif /* !TARGET_OS_IPHONE */
}
4 changes: 0 additions & 4 deletions src/unix/proctitle.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
#include <stdlib.h>
#include <string.h>

extern void uv__set_process_title_platform_init(void);
extern void uv__set_process_title(const char* title);

static uv_mutex_t process_title_mutex;
Expand All @@ -39,9 +38,6 @@ static struct {

static void init_process_title_mutex_once(void) {
uv_mutex_init(&process_title_mutex);
#ifdef __APPLE__
uv__set_process_title_platform_init();
#endif
}


Expand Down
6 changes: 5 additions & 1 deletion test/test-process-title-threadsafe.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@

#include <string.h>

#define NUM_ITERATIONS 50
#ifdef __APPLE__
# define NUM_ITERATIONS 10
#else
# define NUM_ITERATIONS 50
#endif

static const char* titles[] = {
"8L2NY0Kdj0XyNFZnmUZigIOfcWjyNr0SkMmUhKw99VLUsZFrvCQQC3XIRfNR8pjyMjXObllled",
Expand Down

0 comments on commit a49bbfd

Please sign in to comment.