16#include <dispatch/dispatch.h>
17#include <CoreFoundation/CoreFoundation.h>
18#include <CoreServices/CoreServices.h>
19#include <objc/runtime.h>
20#include <objc/message.h>
70static void __attribute__((constructor)) VuoCompositionLoader_init(
void)
74#pragma clang diagnostic push
75#pragma clang diagnostic ignored "-Wdeprecated-declarations"
79#pragma clang diagnostic pop
104 if (reply != expectedReply)
105 VUserLog(
"The composition loader received the wrong message from the composition (expected %d, received %d)", expectedReply, reply);
111int main(
int argc,
char **argv)
113 char *loaderControlURL = NULL;
117 static struct option options[] = {
118 {
"vuo-control", required_argument, NULL, 0},
119 {
"vuo-telemetry", required_argument, NULL, 0},
120 {
"vuo-loader", required_argument, NULL, 0},
121 {
"vuo-runner-pipe", required_argument, NULL, 0},
122 {
"vuo-continue-if-runner-dies", no_argument, NULL, 0},
123 {
"vuo-runner-pid", required_argument, NULL, 0},
124 {NULL, no_argument, NULL, 0}
128 while ((ret = getopt_long(argc, argv,
"", options, &optionIndex)) != -1)
142 if (loaderControlURL)
143 free(loaderControlURL);
144 loaderControlURL = strdup(optarg);
159 if (!loaderControlURL)
161 VUserLog(
"Error: Please specify a --vuo-loader URL.");
165 VuoDefer(^{ free(loaderControlURL); });
174 VUserLog(
"The composition couldn't start because the composition loader couldn't establish communication to control the composition : %s", zmq_strerror(errno));
181 VUserLog(
"Couldn't bind self-receive socket: %s (%d)", zmq_strerror(errno), errno);
188 VUserLog(
"Couldn't connect self-send socket: %s (%d)", zmq_strerror(errno), errno);
194 dispatch_queue_t loaderControlQueue;
195 dispatch_source_t loaderControlTimer;
196 dispatch_semaphore_t loaderControlCanceledSemaphore;
198 loaderControlCanceledSemaphore = dispatch_semaphore_create(0);
199 loaderControlQueue = dispatch_queue_create(
"org.vuo.runtime.loader", NULL);
200 loaderControlTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, DISPATCH_TIMER_STRICT, loaderControlQueue);
201 dispatch_source_set_timer(loaderControlTimer, dispatch_walltime(NULL,0), NSEC_PER_SEC/1000, NSEC_PER_SEC/1000);
202 dispatch_source_set_event_handler(loaderControlTimer, ^{
206 zmq_pollitem_t items[]=
213 zmq_poll(items,itemCount,timeout);
214 if(!(items[0].revents & ZMQ_POLLIN))
226 for (
int i = 0; i < numResourceDylibPathsAdded; ++i)
234 for (
int i = 0; i < numResourceDylibPathsRemoved; ++i)
245 zmq_msg_t messages[1];
259 dispatch_source_set_cancel_handler(loaderControlTimer, ^{
260 dispatch_semaphore_signal(loaderControlCanceledSemaphore);
262 dispatch_resume(loaderControlTimer);
280 dispatch_source_cancel(loaderControlTimer);
286 zmq_msg_init_size(&message,
sizeof z);
287 memcpy(zmq_msg_data(&message), &z,
sizeof z);
288 if (zmq_msg_send(&message,
static_cast<zmq_msg_t *
>(
ZMQLoaderSelfSend), 0) == -1)
289 VUserLog(
"Couldn't break: %s (%d)", zmq_strerror(errno), errno);
290 zmq_msg_close(&message);
293 dispatch_semaphore_wait(loaderControlCanceledSemaphore, DISPATCH_TIME_FOREVER);
294 dispatch_release(loaderControlCanceledSemaphore);
295 dispatch_release(loaderControlTimer);
296 dispatch_sync(loaderControlQueue, ^{
301 dispatch_release(loaderControlQueue);
308 VUserLog(
"The composition couldn't stop because vuoFini() couldn't be found in the composition library : %s", dlerror());
335 const char *filename = strrchr(dylibPath,
'/');
338 char *name = strdup(filename + 1);
339 name[strlen(name) - strlen(
"-XXXXXX.dylib")] = 0;
347 void *runtimePersistentState = NULL;
358 VUserLog(
"The composition couldn't be replaced because vuoRuntimeState couldn't be found in '%s' : %s", dylibPath, dlerror());
367 VUserLog(
"The composition couldn't be replaced because vuoSetCompositionDiff() couldn't be found in the composition library : %s", dlerror());
380 VUserLog(
"The composition couldn't be replaced because vuoFini() couldn't be found in the composition library : %s", dlerror());
383 runtimePersistentState =
vuoFini();
404 VUserLog(
"The composition couldn't be replaced because the composition loader couldn't establish communication to control the composition : %s", zmq_strerror(errno));
413 VUserLog(
"The composition couldn't be replaced because the library '%s' couldn't be loaded : %s", dylibPath, dlerror());
420 VUserLog(
"The composition couldn't be replaced because vuoInitInProcess() couldn't be found in '%s' : %s", dylibPath, dlerror());
427 VUserLog(
"The composition couldn't be replaced because vuoIsCurrentCompositionStopped() couldn't be found in '%s' : %s", dylibPath, dlerror());
447 const int timeoutInSeconds = -1;
448 zmq_msg_t messages[2];
460 void *
dylibHandle = dlopen(dylibPath.c_str(), RTLD_NOW);
463 VUserLog(
"The composition couldn't be replaced because the library '%s' couldn't be loaded : %s", dylibPath.c_str(), dlerror());
479 VUserLog(
"The library '%s' couldn't be unloaded because its handle was not found.", dylibPath.c_str());
486 VUserLog(
"The library '%s' couldn't be unloaded : %s", dylibPath.c_str(), dlerror());