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>
69 static void __attribute__((constructor)) VuoCompositionLoader_init(
void)
73 #pragma clang diagnostic push
74 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
78 #pragma clang diagnostic pop
103 if (reply != expectedReply)
104 VUserLog(
"The composition loader received the wrong message from the composition (expected %d, received %d)", expectedReply, reply);
110 int main(
int argc,
char **argv)
112 char *loaderControlURL = NULL;
116 static struct option options[] = {
117 {
"vuo-control", required_argument, NULL, 0},
118 {
"vuo-telemetry", required_argument, NULL, 0},
119 {
"vuo-loader", required_argument, NULL, 0},
120 {
"vuo-runner-pipe", required_argument, NULL, 0},
121 {
"vuo-continue-if-runner-dies", no_argument, NULL, 0},
122 {
"vuo-runner-pid", required_argument, NULL, 0},
123 {NULL, no_argument, NULL, 0}
127 while ((ret = getopt_long(argc, argv,
"", options, &optionIndex)) != -1)
141 if (loaderControlURL)
142 free(loaderControlURL);
143 loaderControlURL = strdup(optarg);
158 if (!loaderControlURL)
160 VUserLog(
"Error: Please specify a --vuo-loader URL.");
164 VuoDefer(^{ free(loaderControlURL); });
173 VUserLog(
"The composition couldn't start because the composition loader couldn't establish communication to control the composition : %s", zmq_strerror(errno));
180 VUserLog(
"Couldn't bind self-receive socket: %s (%d)", zmq_strerror(errno), errno);
187 VUserLog(
"Couldn't connect self-send socket: %s (%d)", zmq_strerror(errno), errno);
193 dispatch_queue_t loaderControlQueue;
194 dispatch_source_t loaderControlTimer;
195 dispatch_semaphore_t loaderControlCanceledSemaphore;
197 loaderControlCanceledSemaphore = dispatch_semaphore_create(0);
198 loaderControlQueue = dispatch_queue_create(
"org.vuo.runtime.loader", NULL);
199 loaderControlTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, DISPATCH_TIMER_STRICT, loaderControlQueue);
200 dispatch_source_set_timer(loaderControlTimer, dispatch_walltime(NULL,0), NSEC_PER_SEC/1000, NSEC_PER_SEC/1000);
201 dispatch_source_set_event_handler(loaderControlTimer, ^{
205 zmq_pollitem_t items[]=
212 zmq_poll(items,itemCount,timeout);
213 if(!(items[0].revents & ZMQ_POLLIN))
225 for (
int i = 0; i < numResourceDylibPathsAdded; ++i)
233 for (
int i = 0; i < numResourceDylibPathsRemoved; ++i)
254 dispatch_source_set_cancel_handler(loaderControlTimer, ^{
255 dispatch_semaphore_signal(loaderControlCanceledSemaphore);
257 dispatch_resume(loaderControlTimer);
275 dispatch_source_cancel(loaderControlTimer);
281 zmq_msg_init_size(&message,
sizeof z);
282 memcpy(zmq_msg_data(&message), &z,
sizeof z);
284 VUserLog(
"Couldn't break: %s (%d)", zmq_strerror(errno), errno);
285 zmq_msg_close(&message);
288 dispatch_semaphore_wait(loaderControlCanceledSemaphore, DISPATCH_TIME_FOREVER);
289 dispatch_release(loaderControlCanceledSemaphore);
290 dispatch_release(loaderControlTimer);
291 dispatch_sync(loaderControlQueue, ^{
296 dispatch_release(loaderControlQueue);
301 VUserLog(
"The composition couldn't stop because vuoFini() couldn't be found in the composition library : %s", dlerror());
323 char *filename = strrchr(dylibPath,
'/');
326 char *name = strdup(filename + 1);
327 name[strlen(name) - strlen(
"-XXXXXX.dylib")] = 0;
335 void *runtimePersistentState = NULL;
346 VUserLog(
"The composition couldn't be replaced because vuoRuntimeState couldn't be found in '%s' : %s", dylibPath, dlerror());
355 VUserLog(
"The composition couldn't be replaced because vuoSetCompositionDiff() couldn't be found in the composition library : %s", dlerror());
368 VUserLog(
"The composition couldn't be replaced because vuoFini() couldn't be found in the composition library : %s", dlerror());
371 runtimePersistentState =
vuoFini();
392 VUserLog(
"The composition couldn't be replaced because the composition loader couldn't establish communication to control the composition : %s", zmq_strerror(errno));
401 VUserLog(
"The composition couldn't be replaced because the library '%s' couldn't be loaded : %s", dylibPath, dlerror());
408 VUserLog(
"The composition couldn't be replaced because vuoInitInProcess() couldn't be found in '%s' : %s", dylibPath, dlerror());
415 VUserLog(
"The composition couldn't be replaced because vuoIsCurrentCompositionStopped() couldn't be found in '%s' : %s", dylibPath, dlerror());
435 const int timeoutInSeconds = -1;
436 zmq_msg_t messages[3];
449 void *
dylibHandle = dlopen(dylibPath.c_str(), RTLD_NOW);
452 VUserLog(
"The composition couldn't be replaced because the library '%s' couldn't be loaded : %s", dylibPath.c_str(), dlerror());
468 VUserLog(
"The library '%s' couldn't be unloaded because its handle was not found.", dylibPath.c_str());
475 VUserLog(
"The library '%s' couldn't be unloaded : %s", dylibPath.c_str(), dlerror());