aboutsummaryrefslogtreecommitdiff
path: root/darwin-bootstrap/bundle-loader.c
diff options
context:
space:
mode:
authorcomex2015-07-11 13:18:41 -0400
committercomex2015-07-11 14:06:16 -0400
commit7de586f0dde91a3bd5433f879f8b614c2ebaf579 (patch)
tree286d5c6fa7b06c5a9623bfefb635e2befb218a42 /darwin-bootstrap/bundle-loader.c
parentstuff! (diff)
downloadsubstitute-7de586f0dde91a3bd5433f879f8b614c2ebaf579.tar.gz
fix?
Diffstat (limited to 'darwin-bootstrap/bundle-loader.c')
-rw-r--r--darwin-bootstrap/bundle-loader.c65
1 files changed, 40 insertions, 25 deletions
diff --git a/darwin-bootstrap/bundle-loader.c b/darwin-bootstrap/bundle-loader.c
index ced3233..9006bf0 100644
--- a/darwin-bootstrap/bundle-loader.c
+++ b/darwin-bootstrap/bundle-loader.c
@@ -30,6 +30,7 @@ static struct {
static pthread_mutex_t hello_reply_mtx = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t hello_reply_cond = PTHREAD_COND_INITIALIZER;
static xxpc_object_t hello_reply;
+static bool hello_reply_ready;
#define GET(funcs, handle, name) (funcs)->name = dlsym(handle, #name)
@@ -113,12 +114,7 @@ static enum bundle_test_result do_bundle_test_type(
}
/* return false if the info was invalid */
-static bool load_bundle_with_info(xxpc_object_t info) {
- if (IB_VERBOSE) {
- char *desc = xxpc_copy_description(info);
- ib_log("load_bundle_with_info: %s", desc);
- free(desc);
- }
+static bool check_bundle_with_info(xxpc_object_t info) {
bool any = xxpc_dictionary_get_bool(info, "any");
enum bundle_test_result btr =
do_bundle_test_type(info, "bundles", cf_has_bundle);
@@ -147,38 +143,47 @@ do_load:;
}
static bool handle_hello_reply(xxpc_object_t dict) {
+ if (IB_VERBOSE) {
+ char *desc = xxpc_copy_description(dict);
+ ib_log("hello_reply: %s", desc);
+ free(desc);
+ }
xxpc_object_t bundles = xxpc_dictionary_get_value(dict, "bundles");
if (!bundles || xxpc_get_type(bundles) != XXPC_TYPE_ARRAY)
return false;
for (size_t i = 0, count = xxpc_array_get_count(bundles);
i < count; i++) {
- if (!load_bundle_with_info(xxpc_array_get_value(bundles, i)))
+ if (!check_bundle_with_info(xxpc_array_get_value(bundles, i)))
return false;
}
return true;
}
+static void signal_hello_reply(xxpc_object_t object) {
+ if (hello_reply_ready)
+ return;
+ pthread_mutex_lock(&hello_reply_mtx);
+ hello_reply = object;
+ hello_reply_ready = true;
+ pthread_cond_signal(&hello_reply_cond);
+ pthread_mutex_unlock(&hello_reply_mtx);
+}
+
static void handle_xxpc_object(xxpc_object_t object, bool is_reply) {
const char *msg;
xxpc_type_t ty = xxpc_get_type(object);
if (ty == XXPC_TYPE_DICTIONARY) {
if (is_reply) {
- pthread_mutex_lock(&hello_reply_mtx);
- hello_reply = object;
- pthread_cond_signal(&hello_reply_cond);
- pthread_mutex_unlock(&hello_reply_mtx);
+ signal_hello_reply(xxpc_retain(object));
return;
}
msg = "received extraneous message from substituted";
- goto complain;
} else if (ty == XXPC_TYPE_ERROR) {
+ signal_hello_reply(NULL);
msg = "XPC error communicating with substituted";
- goto complain;
} else {
msg = "unknown object received from XPC";
- goto complain;
}
-complain:;
char *desc = xxpc_copy_description(object);
ib_log("%s: %s", msg, desc);
free(desc);
@@ -224,24 +229,30 @@ static void init() {
* time changes. */
uint64_t then = mach_absolute_time() + 10 * NSEC_PER_SEC;
pthread_mutex_lock(&hello_reply_mtx);
- while (!hello_reply) {
+ while (!hello_reply_ready) {
uint64_t now = mach_absolute_time();
uint64_t remaining = now >= then ? 0 : then - now;
struct timespec remaining_ts = {.tv_sec = remaining / NSEC_PER_SEC,
.tv_nsec = remaining % NSEC_PER_SEC};
- if (pthread_cond_timedwait_relative_np(&hello_reply_cond, &hello_reply_mtx,
- &remaining_ts)) {
- if (errno == ETIMEDOUT) {
+ int err = pthread_cond_timedwait_relative_np(&hello_reply_cond,
+ &hello_reply_mtx,
+ &remaining_ts);
+ if (err != 0) {
+ if (err == ETIMEDOUT)
ib_log("ACK - didn't receive a reply from substituted in time!");
- goto bad;
- } else {
- ib_log("pthread_cond_timedwait failed");
- goto bad;
- }
+ else
+ ib_log("pthread_cond_timedwait failed: %s", strerror(err));
+ pthread_mutex_unlock(&hello_reply_mtx);
+ goto bad;
}
}
pthread_mutex_unlock(&hello_reply_mtx);
+ if (hello_reply == NULL) {
+ /* thread notified us of XPC error */
+ goto bad;
+ }
+
if (!handle_hello_reply(hello_reply)) {
char *desc = xxpc_copy_description(hello_reply);
ib_log("received invalid message from substituted: %s", desc);
@@ -251,5 +262,9 @@ static void init() {
return;
bad:
- ib_log("giving up...");
+ if (hello_reply) {
+ xxpc_release(hello_reply);
+ hello_reply = NULL;
+ }
+ ib_log("giving up on loading bundles for this process...");
}