26 #include <sys/types.h>
37 static int init_done = 0;
43 static pthread_mutex_t monitor_mutex = PTHREAD_MUTEX_INITIALIZER;
48 static GHashTable *objtype_ops_tab = NULL;
54 static GHashTable *objtype_mutex_tab = NULL;
59 static GHashTable *objtype_objid_obj_tab;
63 static GHashTable *objtype_objid_objstate_tab;
70 static int monitor_objid_idx = 0;
75 static GHashTable *tid_monitor_tab = NULL;
86 static GHashTable *obj_monitor_tab = NULL;
87 static GHashTable *objid_monitor_tab = NULL;
88 static GHashTable *obj_objtype_tab;
89 static GHashTable *objid_objtype_tab;
90 static GHashTable *obj_objid_tab;
91 static GHashTable *objid_obj_tab;
97 pthread_mutex_lock(&monitor_mutex);
100 pthread_mutex_unlock(&monitor_mutex);
104 objtype_ops_tab = g_hash_table_new(g_direct_hash,g_direct_equal);
105 objtype_mutex_tab = g_hash_table_new(g_direct_hash,g_direct_equal);
106 objtype_objid_obj_tab = g_hash_table_new(g_direct_hash,g_direct_equal);
107 objtype_objid_objstate_tab = g_hash_table_new(g_direct_hash,g_direct_equal);
109 tid_monitor_tab = g_hash_table_new(g_direct_hash,g_direct_equal);
111 obj_monitor_tab = g_hash_table_new(g_direct_hash,g_direct_equal);
112 objid_monitor_tab = g_hash_table_new(g_direct_hash,g_direct_equal);
114 obj_objtype_tab = g_hash_table_new(g_direct_hash,g_direct_equal);
115 objid_objtype_tab = g_hash_table_new(g_direct_hash,g_direct_equal);
117 obj_objid_tab = g_hash_table_new(g_direct_hash,g_direct_equal);
118 objid_obj_tab = g_hash_table_new(g_direct_hash,g_direct_equal);
122 pthread_mutex_unlock(&monitor_mutex);
131 pthread_mutex_lock(&monitor_mutex);
134 pthread_mutex_unlock(&monitor_mutex);
138 g_hash_table_destroy(tid_monitor_tab);
140 g_hash_table_destroy(obj_monitor_tab);
141 g_hash_table_destroy(objid_monitor_tab);
143 g_hash_table_destroy(obj_objtype_tab);
144 g_hash_table_destroy(objid_objtype_tab);
146 g_hash_table_destroy(obj_objid_tab);
147 g_hash_table_destroy(objid_obj_tab);
149 g_hash_table_destroy(objtype_objid_objstate_tab);
150 g_hash_table_destroy(objtype_objid_obj_tab);
151 g_hash_table_destroy(objtype_ops_tab);
152 g_hash_table_destroy(objtype_mutex_tab);
156 pthread_mutex_unlock(&monitor_mutex);
164 pthread_mutex_lock(&monitor_mutex);
165 retval = ++monitor_objid_idx;
166 while (g_hash_table_lookup(objid_monitor_tab,(gpointer)(uintptr_t)retval))
168 pthread_mutex_unlock(&monitor_mutex);
176 retval = g_hash_table_lookup(objtype_ops_tab,(gpointer)(uintptr_t)objtype);
184 pthread_mutex_lock(&monitor_mutex);
185 retval = __monitor_lookup_objtype_ops(objtype);
186 pthread_mutex_unlock(&monitor_mutex);
191 static int __monitor_lookup_objid(
int objid,
192 int *objtype,
void **obj,
194 struct monitor *_monitor;
198 _monitor = g_hash_table_lookup(objid_monitor_tab,
199 (gpointer)(uintptr_t)objid);
202 _objtype = (int)(uintptr_t)g_hash_table_lookup(objid_objtype_tab,
203 (gpointer)(uintptr_t)objid);
205 vwarn(
"bad objtype %d for obj %p monitor %p!\n",_objtype,obj,_monitor);
206 _obj = g_hash_table_lookup(objid_obj_tab,
207 (gpointer)(uintptr_t)objid);
220 int *objtype,
void **obj,
221 struct monitor **monitor) {
224 pthread_mutex_lock(&monitor_mutex);
225 retval = __monitor_lookup_objid(objid,objtype,obj,monitor);
226 pthread_mutex_unlock(&monitor_mutex);
232 pthread_mutex_t *
mutex;
234 mutex = (pthread_mutex_t *)g_hash_table_lookup(objtype_mutex_tab,
235 (gpointer)(uintptr_t)objtype);
239 pthread_mutex_lock(mutex);
246 pthread_mutex_lock(&monitor_mutex);
248 pthread_mutex_unlock(&monitor_mutex);
254 pthread_mutex_t *
mutex;
256 mutex = (pthread_mutex_t *)g_hash_table_lookup(objtype_mutex_tab,
257 (gpointer)(uintptr_t)objtype);
261 pthread_mutex_unlock(mutex);
268 pthread_mutex_lock(&monitor_mutex);
270 pthread_mutex_unlock(&monitor_mutex);
282 GHashTable *tmp_objid_obj_tab;
288 pthread_mutex_lock(&monitor_mutex);
292 pthread_mutex_unlock(&monitor_mutex);
295 tmp_objid_obj_tab = (GHashTable *) \
296 g_hash_table_lookup(objtype_objid_obj_tab,(gpointer)(uintptr_t)objtype);
297 if (!tmp_objid_obj_tab) {
298 pthread_mutex_unlock(&monitor_mutex);
302 retval = array_list_create(g_hash_table_size(tmp_objid_obj_tab));
303 g_hash_table_iter_init(&iter,tmp_objid_obj_tab);
304 while (g_hash_table_iter_next(&iter,&objid,&obj)) {
305 if (!include_null && !obj)
307 array_list_append(retval,objid);
310 pthread_mutex_unlock(&monitor_mutex);
318 GHashTable *tmp_objid_obj_tab;
323 pthread_mutex_lock(&monitor_mutex);
327 pthread_mutex_unlock(&monitor_mutex);
330 tmp_objid_obj_tab = (GHashTable *) \
331 g_hash_table_lookup(objtype_objid_obj_tab,(gpointer)(uintptr_t)objtype);
332 if (!tmp_objid_obj_tab) {
333 pthread_mutex_unlock(&monitor_mutex);
337 retval = array_list_create(g_hash_table_size(tmp_objid_obj_tab));
338 g_hash_table_iter_init(&iter,tmp_objid_obj_tab);
339 while (g_hash_table_iter_next(&iter,NULL,&obj)) {
340 if (!include_null && !obj)
342 array_list_append(retval,obj);
345 pthread_mutex_unlock(&monitor_mutex);
351 void **obj,
struct monitor **monitor) {
354 pthread_mutex_lock(&monitor_mutex);
357 verror(
"could not find objtype %d -- BUG!\n",objtype);
358 pthread_mutex_unlock(&monitor_mutex);
361 retval = __monitor_lookup_objid(objid,NULL,obj,monitor);
367 pthread_mutex_unlock(&monitor_mutex);
374 struct monitor **monitor) {
376 struct monitor *_monitor;
378 pthread_mutex_lock(&monitor_mutex);
381 verror(
"could not find objtype %d -- BUG!\n",objtype);
382 pthread_mutex_unlock(&monitor_mutex);
385 retval = __monitor_lookup_objid(objid,NULL,obj,&_monitor);
386 if (retval && monitor)
388 if (retval && _monitor)
389 pthread_mutex_lock(&_monitor->
mutex);
395 pthread_mutex_unlock(&monitor_mutex);
401 int *objtype,
void **obj,
402 struct monitor **monitor) {
404 struct monitor *_monitor;
406 pthread_mutex_lock(&monitor_mutex);
407 retval = __monitor_lookup_objid(objid,objtype,obj,&_monitor);
408 if (retval && monitor)
410 if (retval && _monitor)
411 pthread_mutex_lock(&_monitor->
mutex);
412 pthread_mutex_unlock(&monitor_mutex);
417 static int __monitor_lookup_obj(
void *obj,
418 int *objtype,
int *objid,
419 struct monitor **monitor) {
420 struct monitor *_monitor;
424 _monitor = g_hash_table_lookup(obj_monitor_tab,obj);
427 _objtype = (int)(uintptr_t)g_hash_table_lookup(obj_objtype_tab,obj);
429 vwarn(
"bad objtype %d for obj %p monitor %p!\n",_objtype,obj,_monitor);
430 _objid = (int)(uintptr_t)g_hash_table_lookup(obj_objid_tab,obj);
432 vwarn(
"bad objid %d for obj %p monitor %p!\n",_objid,obj,_monitor);
445 int *objtype,
int *objid,
446 struct monitor **monitor) {
449 pthread_mutex_lock(&monitor_mutex);
450 retval = __monitor_lookup_obj(obj,objtype,objid,monitor);
451 pthread_mutex_unlock(&monitor_mutex);
457 int *objtype,
int *objid,
458 struct monitor **monitor) {
460 struct monitor *_monitor;
462 pthread_mutex_lock(&monitor_mutex);
463 retval = __monitor_lookup_obj(obj,objtype,objid,&_monitor);
464 if (retval && monitor)
466 if (retval && _monitor)
467 pthread_mutex_lock(&_monitor->
mutex);
468 pthread_mutex_unlock(&monitor_mutex);
474 static int __monitor_add_obj(
struct monitor *monitor,
475 int objid,
int objtype,
void *obj,
void *objstate) {
481 struct monitor *_monitor = NULL;
484 if (!(ops = __monitor_lookup_objtype_ops(objtype))) {
485 verror(
"unknown objtype %d!\n",objtype);
490 if (__monitor_lookup_objid(objid,&_objtype,&_obj,&_monitor)) {
491 verror(
"obj %d (%p) already being monitored!\n",objid,_obj);
496 if (obj && __monitor_lookup_obj(obj,&_objtype,&_objid,&_monitor)) {
497 verror(
"obj %d (%p) already being monitored!\n",_objid,obj);
505 g_hash_table_insert(obj_monitor_tab,obj,monitor);
506 g_hash_table_insert(objid_monitor_tab,(gpointer)(uintptr_t)objid,monitor);
508 g_hash_table_insert(obj_objtype_tab,obj,(gpointer)(uintptr_t)objtype);
509 g_hash_table_insert(objid_objtype_tab,(gpointer)(uintptr_t)objid,
510 (gpointer)(uintptr_t)objtype);
512 g_hash_table_insert(objid_obj_tab,(gpointer)(uintptr_t)objid,obj);
513 g_hash_table_insert(obj_objid_tab,obj,(gpointer)(uintptr_t)objid);
521 verror(
"could not attach evloop to objid %d (%p)!\n",objid,obj);
523 g_hash_table_remove(obj_monitor_tab,obj);
524 g_hash_table_remove(objid_monitor_tab,(gpointer)(uintptr_t)objid);
526 g_hash_table_remove(obj_objtype_tab,obj);
527 g_hash_table_remove(objid_objtype_tab,(gpointer)(uintptr_t)objid);
529 g_hash_table_remove(objid_obj_tab,(gpointer)(uintptr_t)objid);
530 g_hash_table_remove(obj_objid_tab,obj);
536 tmp_tab = (GHashTable *) \
537 g_hash_table_lookup(objtype_objid_obj_tab,(gpointer)(uintptr_t)objtype);
538 g_hash_table_insert(tmp_tab,(gpointer)(uintptr_t)objid,obj);
540 tmp_tab = (GHashTable *)g_hash_table_lookup(objtype_objid_objstate_tab,
541 (gpointer)(uintptr_t)objtype);
542 g_hash_table_insert(tmp_tab,(gpointer)(uintptr_t)objid,objstate);
558 pthread_mutex_lock(&monitor_mutex);
559 pthread_mutex_lock(&monitor->
mutex);
561 retval = __monitor_add_obj(monitor,objid,objtype,obj,objstate);
563 pthread_mutex_unlock(&monitor->
mutex);
564 pthread_mutex_unlock(&monitor_mutex);
569 static int __monitor_close_obj(
struct monitor *monitor,
570 int objid,
int objtype,
void *obj,
571 int kill,
int kill_sig,
572 GHashTable *iter_hashtable) {
578 struct monitor *_monitor = NULL;
581 if (!(ops = __monitor_lookup_objtype_ops(objtype))) {
582 verror(
"unknown objtype %d!\n",objtype);
587 if (!__monitor_lookup_objid(objid,&_objtype,&_obj,&_monitor)) {
588 vwarn(
"objid %d (%p) not being monitored!\n",objid,obj);
593 if (!__monitor_lookup_obj(obj,&_objtype,&_objid,&_monitor)) {
594 vwarn(
"objid %d (%p) not being monitored!\n",objid,obj);
607 verror(
"error detaching evloop from objid %d (%p)!\n",objid,obj);
613 if (ops->
close && ops->
close(monitor,obj,objstate,kill,kill_sig)) {
614 verror(
"error closing objid %d (kill = %d, kill_sig %d)!\n",
615 objid,kill,kill_sig);
623 int kill,
int kill_sig) {
627 struct monitor *_monitor = NULL;
629 pthread_mutex_lock(&monitor_mutex);
630 pthread_mutex_lock(&monitor->
mutex);
632 if (!__monitor_lookup_obj(obj,&objtype,&objid,&_monitor) || !_monitor) {
633 verror(
"could not lookup obj %p!\n",obj);
635 pthread_mutex_unlock(&monitor->
mutex);
636 pthread_mutex_unlock(&monitor_mutex);
640 retval = __monitor_close_obj(monitor,objid,objtype,obj,kill,kill_sig,NULL);
642 pthread_mutex_unlock(&monitor->
mutex);
643 pthread_mutex_unlock(&monitor_mutex);
649 int kill,
int kill_sig) {
653 struct monitor *_monitor = NULL;
655 pthread_mutex_lock(&monitor_mutex);
656 pthread_mutex_lock(&monitor->
mutex);
658 if (!__monitor_lookup_objid(objid,&objtype,&obj,&_monitor) || !_monitor) {
659 verror(
"could not lookup objid %d!\n",objid);
661 pthread_mutex_unlock(&monitor->
mutex);
662 pthread_mutex_unlock(&monitor_mutex);
666 retval = __monitor_close_obj(monitor,objid,objtype,obj,kill,kill_sig,NULL);
668 pthread_mutex_unlock(&monitor->
mutex);
669 pthread_mutex_unlock(&monitor_mutex);
674 static int __monitor_del_obj(
struct monitor *monitor,
675 int objid,
int objtype,
void *obj,
676 GHashTable *iter_hashtable) {
682 struct monitor *_monitor = NULL;
686 if (!(ops = __monitor_lookup_objtype_ops(objtype))) {
687 verror(
"unknown objtype %d!\n",objtype);
692 if (!__monitor_lookup_objid(objid,&_objtype,&_obj,&_monitor)) {
693 vwarn(
"objid %d (%p) not being monitored!\n",objid,obj);
698 if (!__monitor_lookup_obj(obj,&_objtype,&_objid,&_monitor)) {
699 vwarn(
"objid %d (%p) not being monitored!\n",objid,obj);
706 tmp_tab = (GHashTable *) \
707 g_hash_table_lookup(objtype_objid_obj_tab,(gpointer)(uintptr_t)objtype);
708 g_hash_table_remove(tmp_tab,(gpointer)(uintptr_t)objid);
709 tmp_tab = (GHashTable *)g_hash_table_lookup(objtype_objid_objstate_tab,
710 (gpointer)(uintptr_t)objtype);
711 objstate = g_hash_table_lookup(tmp_tab,(gpointer)(uintptr_t)objid);
712 g_hash_table_remove(tmp_tab,(gpointer)(uintptr_t)objid);
721 verror(
"could not detach evloop from objid %d (%p);"
722 " removing anyway!\n",objid,obj);
728 if (ops->
close && ops->
close(monitor,obj,objstate,0,0)) {
729 verror(
"could not close objid %d; removing anyway!\n",objid);
734 if (ops->
fini && ops->
fini(monitor,obj,objstate)) {
735 verror(
"could not fini objid %d; removing anyway!\n",objid);
742 if (iter_hashtable != obj_monitor_tab)
743 g_hash_table_remove(obj_monitor_tab,obj);
744 if (iter_hashtable != objid_monitor_tab)
745 g_hash_table_remove(objid_monitor_tab,(gpointer)(uintptr_t)objid);
747 if (iter_hashtable != obj_objtype_tab)
748 g_hash_table_remove(obj_objtype_tab,obj);
749 if (iter_hashtable != objid_objtype_tab)
750 g_hash_table_remove(objid_objtype_tab,(gpointer)(uintptr_t)objid);
752 if (iter_hashtable != objid_obj_tab)
753 g_hash_table_remove(objid_obj_tab,(gpointer)(uintptr_t)objid);
754 if (iter_hashtable != objid_obj_tab)
755 g_hash_table_remove(objid_obj_tab,obj);
767 struct monitor *_monitor = NULL;
769 pthread_mutex_lock(&monitor_mutex);
770 pthread_mutex_lock(&monitor->
mutex);
772 if (!__monitor_lookup_obj(obj,&objtype,&objid,&_monitor) || !_monitor) {
773 verror(
"could not lookup obj %p!\n",obj);
775 pthread_mutex_unlock(&monitor->
mutex);
776 pthread_mutex_unlock(&monitor_mutex);
780 retval = __monitor_del_obj(monitor,objid,objtype,obj,NULL);
782 pthread_mutex_unlock(&monitor->
mutex);
783 pthread_mutex_unlock(&monitor_mutex);
792 struct monitor *_monitor = NULL;
794 pthread_mutex_lock(&monitor_mutex);
795 pthread_mutex_lock(&monitor->
mutex);
797 if (!__monitor_lookup_objid(objid,&objtype,&obj,&_monitor) || !_monitor) {
798 verror(
"could not lookup objid %d!\n",objid);
800 pthread_mutex_unlock(&monitor->
mutex);
801 pthread_mutex_unlock(&monitor_mutex);
805 retval = __monitor_del_obj(monitor,objid,objtype,obj,NULL);
807 pthread_mutex_unlock(&monitor->
mutex);
808 pthread_mutex_unlock(&monitor_mutex);
817 static int __monitor_shutdown(
struct monitor *monitor) {
822 struct monitor *_monitor;
828 if (monitor->
mtid == 0) {
830 "monitor thread already gone, nothing to do\n");
834 if (!pthread_equal(pthread_self(),monitor->
mtid)) {
835 verror(
"only monitor thread can shutdown itself!\n");
845 g_hash_table_iter_init(&iter,obj_monitor_tab);
846 while (g_hash_table_iter_next(&iter,&obj,(gpointer *)&_monitor)) {
847 if (monitor == _monitor) {
848 if (!__monitor_lookup_obj(obj,&objtype,&objid,NULL))
849 verror(
"could not lookup obj %p to close it!\n",obj);
852 __monitor_close_obj(monitor,objid,objtype,obj,0,0,obj_monitor_tab);
864 vwarn(
"BUG: child_recv_fd still live!\n");
873 vwarn(
"BUG: child_send_fd still live %d!\n",getpid());
895 vwarn(
"BUG: p.stdin_c_fd still live!\n");
906 vwarn(
"BUG: p.stdout_c_fd still live!\n");
921 vwarn(
"BUG: p.stderr_c_fd still live!\n");
942 g_hash_table_remove(tid_monitor_tab,(gpointer)(uintptr_t)monitor->
mtid);
950 pthread_mutex_lock(&monitor_mutex);
951 pthread_mutex_lock(&monitor->
mutex);
953 rc = __monitor_shutdown(monitor);
955 pthread_mutex_unlock(&monitor->
mutex);
956 pthread_mutex_unlock(&monitor_mutex);
961 static int __monitor_destroy(
struct monitor *monitor) {
966 struct monitor *_monitor;
969 if (monitor->
mtid == 0) {
971 "monitor thread already gone, nothing to do\n");
979 if (pthread_kill(monitor->
mtid,0) == 0
980 && !pthread_equal(pthread_self(),monitor->
mtid)) {
981 verror(
"only monitor thread can destroy itself!\n");
989 __monitor_shutdown(monitor);
996 g_hash_table_iter_init(&iter,obj_monitor_tab);
997 while (g_hash_table_iter_next(&iter,&obj,(gpointer *)&_monitor)) {
998 if (monitor == _monitor) {
1001 if (!__monitor_lookup_obj(obj,&objtype,&objid,NULL))
1002 verror(
"could not lookup obj %p to free it!\n",obj);
1005 __monitor_del_obj(monitor,objid,objtype,obj,obj_monitor_tab);
1008 g_hash_table_iter_remove(&iter);
1042 pthread_mutex_lock(&monitor_mutex);
1043 pthread_mutex_lock(&monitor->
mutex);
1045 rc = __monitor_destroy(monitor);
1047 pthread_mutex_unlock(&monitor_mutex);
1053 pthread_mutex_t *
mutex) {
1054 pthread_mutex_lock(&monitor_mutex);
1056 if (g_hash_table_lookup(objtype_ops_tab,(gpointer)(uintptr_t)objtype)) {
1057 verror(
"monitor objtype %d already exists!\n",objtype);
1059 pthread_mutex_unlock(&monitor_mutex);
1063 g_hash_table_insert(objtype_ops_tab,(gpointer)(uintptr_t)objtype,ops);
1065 g_hash_table_insert(objtype_mutex_tab,(gpointer)(uintptr_t)objtype,
1067 g_hash_table_insert(objtype_objid_obj_tab,(gpointer)(uintptr_t)objtype,
1068 g_hash_table_new(g_direct_hash,g_direct_equal));
1069 g_hash_table_insert(objtype_objid_objstate_tab,(gpointer)(uintptr_t)objtype,
1070 g_hash_table_new(g_direct_hash,g_direct_equal));
1072 pthread_mutex_unlock(&monitor_mutex);
1078 struct monitor *monitor = (
struct monitor *)state;
1100 "could not recv msg on fd %d; closing!\n",fd);
1109 "could not lookup objid %d; ignoring msg!\n",msg->
objid);
1114 ops = monitor_lookup_objtype_ops(objtype);
1117 "unknown objtype %d; ignoring msg!\n",objtype);
1123 "defhandler: recv type(%d) objid(%d) %d:%d '%s' (%d)\n",
1139 struct monitor *monitor = (
struct monitor *)state;
1153 "could not recv msg on fd %d; closing!\n",fd);
1162 "could not lookup objid %d; ignoring msg!\n",msg->
objid);
1167 ops = monitor_lookup_objtype_ops(objtype);
1170 "unknown objtype %d; ignoring msg\n",objtype);
1176 "defhandler: recv type(%d) objid(%d) %hd:%hd '%s' (%d)\n",
1195 while (rc < count) {
1196 retval = write(fd,buf + rc,count - rc);
1200 else if (errno == EAGAIN || errno == EWOULDBLOCK) {
1204 verror(
"write(%d): %s\n",fd,strerror(errno));
1215 static int __monitor_stdout_evh(
int fd,
int fdtype,
void *state) {
1216 struct monitor *monitor = (
struct monitor *)state;
1219 void *callback_state;
1237 verror(
"unknown stdout/err fd %d -- BUG!\n",fd);
1241 while (rc < (
int)
sizeof(buf)) {
1242 retval = read(fd,buf + rc,
sizeof(buf) - 1 - rc);
1246 else if (errno == EAGAIN || errno == EWOULDBLOCK) {
1248 if (callback && rc) {
1250 callback(fd,buf,rc,callback_state);
1257 verror(
"read(%d): %s (closing)\n",fd,strerror(errno));
1261 else if (retval == 0) {
1262 if (rc && callback) {
1264 callback(fd,buf,rc,callback_state);
1273 if (rc == (
sizeof(buf) - 1)) {
1276 callback(fd,buf,rc,callback_state);
1302 static int __monitor_stdin_evh(
int fd,
int fdtype,
void *state) {
1303 struct monitor *monitor = (
struct monitor *)state;
1305 void *callback_state;
1310 if (fd == STDIN_FILENO) {
1315 verror(
"unknown stdin fd %d -- BUG!\n",fd);
1320 retval = read(fd,buf + rc,
sizeof(buf) - rc);
1324 else if (errno == EAGAIN || errno == EWOULDBLOCK) {
1326 if (callback && rc) {
1328 callback(fd,buf,rc,callback_state);
1333 verror(
"read(%d): %s (closing)\n",fd,strerror(errno));
1338 else if (retval == 0) {
1339 if (rc && callback) {
1341 callback(fd,buf,rc,callback_state);
1349 if (retval ==
sizeof(buf)) {
1352 callback(fd,buf,rc,callback_state);
1362 static int __monitor_eh(
int errortype,
int fd,
int fdtype,
1364 struct monitor *monitor = NULL;
1367 monitor = (
struct monitor *)fdinfo->
rhstate;
1369 monitor = (
struct monitor *)fdinfo->
whstate;
1371 monitor = (
struct monitor *)fdinfo->
xhstate;
1374 verror(
"no monitor state to handle evloop error -- double fault!\n");
1389 verror(
"BUG: error on monitor pipe fd %d: %d\n",fd,errortype);
1392 verror(
"BUG: error on monitor child pid waitpipe fd %d: %d\n",
1398 verror(
"BUG: error on monitor stdio fd %d: %d\n",fd,errortype);
1401 verror(
"BUG: evloop error on a non-monitor descriptor %d: %d\n",
1409 int objid,
int objtype,
void *obj,
void *objstate);
1412 int objid,
int objtype,
void *obj,
void *objstate,
1417 int req_pipe[2] = { -1,-1 };
1418 int rep_pipe[2] = { -1,-1 };
1421 verror(
"unknown monitor type %d\n",type);
1433 if (!(ops = monitor_lookup_objtype_ops(objtype))) {
1434 verror(
"unknown objtype %d!\n",objtype);
1439 monitor =
calloc(1,
sizeof(*monitor));
1441 monitor->
type = type;
1442 monitor->
flags = flags;
1443 monitor->
mtid = pthread_self();
1445 pthread_mutex_init(&monitor->
mutex,NULL);
1447 monitor->
msg_obj_tab = g_hash_table_new(g_direct_hash,g_direct_equal);
1452 if (pipe(req_pipe)) {
1453 verror(
"pipe: %s\n",strerror(errno));
1460 monitor->
p.
pid = -1;
1463 if (pipe(rep_pipe)) {
1464 verror(
"pipe: %s\n",strerror(errno));
1484 if (custom_child_recv_evh)
1487 custom_child_recv_evh,monitor);
1500 if (custom_recv_evh)
1503 custom_recv_evh,monitor);
1524 pthread_mutex_lock(&monitor_mutex);
1525 pthread_mutex_lock(&monitor->
mutex);
1527 g_hash_table_insert(tid_monitor_tab,
1528 (gpointer)(uintptr_t)monitor->
mtid,monitor);
1531 pthread_mutex_unlock(&monitor->
mutex);
1532 pthread_mutex_unlock(&monitor_mutex);
1536 pthread_mutex_unlock(&monitor->
mutex);
1537 pthread_mutex_unlock(&monitor_mutex);
1546 if (req_pipe[0] > -1)
1548 if (req_pipe[1] > -1)
1550 if (rep_pipe[0] > -1)
1552 if (rep_pipe[1] > -1)
1560 int objid,
int objtype,
void *obj,
void *objstate) {
1564 monitor->
objid = objid;
1567 if (__monitor_add_obj(monitor,monitor->
objid,objtype,obj,objstate)) {
1568 monitor->
objid = -1;
1569 monitor->
obj = NULL;
1577 int objid,
int objtype,
void *obj,
void *objstate) {
1583 pthread_mutex_lock(&monitor_mutex);
1584 pthread_mutex_lock(&monitor->
mutex);
1588 pthread_mutex_unlock(&monitor->
mutex);
1589 pthread_mutex_unlock(&monitor_mutex);
1595 int objid,
int objtype,
void *obj,
void *objstate) {
1617 int objtype,
void *obj,
void *objstate,
1620 void *callback_state) {
1624 verror(
"can only attach to process-based monitors! (%d)\n",type);
1635 monitor =
calloc(1,
sizeof(*monitor));
1639 monitor->
mtid = pthread_self();
1643 pthread_mutex_init(&monitor->
mutex,NULL);
1645 monitor->
msg_obj_tab = g_hash_table_new(g_direct_hash,g_direct_equal);
1656 verror(
"no objid set by parent!\n");
1686 vwarn(
"could not enable bidirectional communication; bad envvar fd!\n");
1687 monitor->
flags &= ~MONITOR_FLAG_BIDI;
1692 vwarn(
"could not enable bidirectional communication; no envvar fd!\n");
1693 monitor->
flags &= ~MONITOR_FLAG_BIDI;
1704 if (custom_child_recv_evh)
1707 custom_child_recv_evh,monitor);
1725 __monitor_stdin_evh,monitor);
1731 pthread_mutex_lock(&monitor_mutex);
1732 pthread_mutex_lock(&monitor->
mutex);
1737 if (obj && __monitor_add_obj(monitor,monitor->
objid,objtype,obj,objstate)) {
1738 pthread_mutex_unlock(&monitor->
mutex);
1739 pthread_mutex_unlock(&monitor_mutex);
1743 pthread_mutex_unlock(&monitor->
mutex);
1744 pthread_mutex_unlock(&monitor_mutex);
1763 struct monitor *monitor = (
struct monitor *)state;
1767 vwarn(
"called again even with no input remaining!\n");
1777 if (errno == EAGAIN || errno == EWOULDBLOCK)
1779 else if (errno == EINTR)
1781 else if (errno == EPIPE) {
1782 vwarn(
"child closed read stdin unexpectedly?\n");
1787 verror(
"error(wrote %d of %d bytes stdin): write: %s\n",
1819 int pipefds[2] = { -1,-1 };
1823 verror(
"invalid monitor type %d\n",monitor->
type);
1827 if (pipe(pipefds)) {
1828 verror(
"pipe: %s\n",strerror(errno));
1837 fcntl(pipefds[1],F_SETFL,fcntl(pipefds[1],F_GETFL) | O_NONBLOCK);
1850 void *callback_state) {
1851 int pipefds[2] = { -1,-1 };
1855 verror(
"invalid monitor type %d\n",monitor->
type);
1859 if (stdout_logfile) {
1861 open(stdout_logfile,O_RDWR | O_CREAT | O_APPEND | O_TRUNC,
1862 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
1864 verror(
"could not open stdout logfile %s!\n",stdout_logfile);
1870 if (pipe(pipefds)) {
1871 verror(
"pipe: %s\n",strerror(errno));
1900 void *callback_state) {
1901 int pipefds[2] = { -1,-1 };
1905 verror(
"invalid monitor type %d\n",monitor->
type);
1909 if (stderr_logfile) {
1911 open(stderr_logfile,O_RDWR | O_CREAT | O_APPEND | O_TRUNC,
1912 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
1914 verror(
"could not open stderr logfile %s!\n",stderr_logfile);
1920 if (pipe(pipefds)) {
1921 verror(
"pipe: %s\n",strerror(errno));
1947 static int __monitor_pid_evh(
int fd,
int fdtype,
void *state) {
1948 struct monitor *monitor = (
struct monitor *)state;
1957 if (waitpid(pid,&status,0) < 0) {
1958 verror(
"waitpid(%d): %s; continuing but sig may be lost!\n",
1959 pid,strerror(errno));
1963 if (WIFCONTINUED(status)) {
1965 "monitored child %d CONTinued; ignoring\n",pid);
1968 else if (WIFSTOPPED(status)) {
1970 "monitored child %d STOPped; ignoring\n",pid);
1973 else if (WIFSIGNALED(status)) {
1975 "monitored child %d terminated by signal %d\n",
1976 pid,WTERMSIG(status));
1978 else if (WIFEXITED(status)) {
1980 "monitored child %d exited with status %d (0x%x)\n",
1981 pid,WEXITSTATUS(status),WEXITSTATUS(status));
1984 verror(
"waitpid(%d): unrecognized status; ignoring!\n",pid);
2003 char *
const argv[],
char *
const envp[],
char *dir) {
2014 verror(
"cannot handle a non-MONITOR_TYPE_PROCESS!\n");
2020 if (!getcwd(cwd,PATH_MAX)) {
2021 verror(
"getcwd: %s\n",strerror(errno));
2025 verror(
"chdir(%s): %s!\n",dir,strerror(errno));
2033 verror(
"fork: %s\n",strerror(errno));
2047 envp_actual =
calloc(envlen + 4,
sizeof(
char *));
2051 while (i < envlen) {
2052 envp_actual[
i] = envp[
i];
2059 snprintf(envvarbuf,
sizeof(envvarbuf),
"%s=%d",
2061 envp_actual[
i] = strdup(envvarbuf);
2063 envp_actual[
i] = NULL;
2066 snprintf(envvarbuf,
sizeof(envvarbuf),
"%s=%d",
2068 envp_actual[
i] = strdup(envvarbuf);
2070 envp_actual[
i] = NULL;
2073 snprintf(envvarbuf,
sizeof(envvarbuf),
"%s=%d",
2075 envp_actual[
i] = strdup(envvarbuf);
2077 envp_actual[
i] = NULL;
2084 verror(
"dup2(%d,stdin): %s; closing stdin!\n",
2086 close(STDIN_FILENO);
2090 close(STDIN_FILENO);
2095 verror(
"dup2(%d,stdout): %s; ignoring!\n",
2102 verror(
"dup2(%d,stderr): %s; ignoring!\n",
2116 while (sptr && *sptr) {
2125 while (sptr && *sptr) {
2134 sigprocmask(0,NULL,&set);
2135 sigprocmask(SIG_UNBLOCK,(
const sigset_t *)&set,NULL);
2139 if (execve(filename,argv,envp_actual)) {
2140 verror(
"execve(%s): %s!\n",filename,strerror(errno));
2150 if (dir && chdir(cwd)) {
2151 verror(
"chdir(%s): %s!\n",cwd,strerror(errno));
2174 if (errno == EINVAL) {
2175 verror(
"could not wait on pid %d: %s; continuing anyway!\n",
2176 pid,strerror(errno));
2212 static int __monitor_error_evh(
int errortype,
int fd,
int fdtype,
2219 errortype,fd,fdtype);
2234 pthread_mutex_lock(&monitor->
mutex);
2235 retval = monitor->
p.
pid > -1 ? 1 : 0;
2236 pthread_mutex_unlock(&monitor->
mutex);
2244 pthread_mutex_lock(&monitor->
mutex);
2246 pthread_mutex_unlock(&monitor->
mutex);
2253 GHashTableIter iter;
2254 struct monitor *_monitor;
2256 pthread_mutex_lock(&monitor_mutex);
2257 pthread_mutex_lock(&monitor->
mutex);
2259 g_hash_table_iter_init(&iter,objid_monitor_tab);
2260 while (g_hash_table_iter_next(&iter,NULL,(gpointer *)&_monitor)) {
2261 if (monitor == _monitor)
2265 pthread_mutex_unlock(&monitor->
mutex);
2266 pthread_mutex_unlock(&monitor_mutex);
2277 GHashTableIter iter;
2282 struct monitor *_monitor;
2289 if (monitor->
mtid == 0) {
2291 "monitor thread already gone, nothing to do\n");
2300 if (pthread_kill(monitor->
mtid,0) == 0
2301 && !pthread_equal(pthread_self(),monitor->
mtid)) {
2302 verror(
"only monitor thread can run!\n");
2308 vwarn(
"monitor (0x%lx) is done!\n",monitor->
mtid);
2314 vwarn(
"monitor (0x%lx) is done!\n",monitor->
mtid);
2328 pthread_mutex_lock(&monitor_mutex);
2329 pthread_mutex_lock(&monitor->
mutex);
2341 "monitor (0x%lx) child (%d) finished\n",
2345 __monitor_lookup_obj(monitor->
obj,&objtype,NULL,NULL);
2346 ops = __monitor_lookup_objtype_ops(objtype);
2348 if (ops && ops->
event)
2354 "monitor (0x%lx) child (%d) still running\n",
2360 "checking status of monitor (0x%lx) objs\n",monitor->
mtid);
2364 g_hash_table_iter_init(&iter,objid_monitor_tab);
2365 while (g_hash_table_iter_next(&iter,&key,(gpointer *)&_monitor)) {
2366 if (monitor != _monitor)
2369 tobjid = (int)(uintptr_t)key;
2371 if (!__monitor_lookup_objid(tobjid,&objtype,&tobj,NULL)) {
2372 verror(
"could not lookup objid %d to check its status!\n",
2376 ops = __monitor_lookup_objtype_ops(objtype);
2380 "objid %d attached = %d\n",tobjid,rc);
2394 "monitor (0x%lx) has no children nor live objects"
2395 " (%d objects total)\n",
2397 pthread_mutex_unlock(&monitor_mutex);
2398 pthread_mutex_unlock(&monitor->
mutex);
2403 pthread_mutex_unlock(&monitor_mutex);
2404 pthread_mutex_unlock(&monitor->
mutex);
2406 verror(
"monitor (0x%lx) has no more FDs in evloop, but has"
2407 " %d children and %d live objs (%d total objs)!\n",
2417 "monitor (0x%lx) has %d children and %d live objs"
2418 " (%d total objs); continuing\n",
2421 pthread_mutex_unlock(&monitor_mutex);
2422 pthread_mutex_unlock(&monitor->
mutex);
2432 verror(
"fatal uncaught error from evloop_handleone, cleaning up!\n");
2437 g_hash_table_iter_init(&iter,objid_monitor_tab);
2438 while (g_hash_table_iter_next(&iter,&key,(gpointer *)&_monitor)) {
2439 if (monitor == _monitor) {
2442 tobjid = (int)(uintptr_t)key;
2444 if (!__monitor_lookup_objid(tobjid,&objtype,&tobj,NULL)) {
2445 verror(
"could not lookup objid %d to deliver fatal error!\n",
2449 ops = __monitor_lookup_objtype_ops(objtype);
2455 __monitor_del_obj(monitor,tobjid,objtype,tobj,obj_monitor_tab);
2457 g_hash_table_iter_remove(&iter);
2464 pthread_mutex_unlock(&monitor_mutex);
2465 pthread_mutex_unlock(&monitor->
mutex);
2475 static void __monitor_store_msg_obj(
struct monitor *monitor,
2481 (gpointer)(uintptr_t)msg->
id,msg->
msg_obj);
2494 static void *monitor_peek_msg_obj(
struct monitor *monitor,
2499 retval = (
void *)g_hash_table_lookup(monitor->
msg_obj_tab,
2500 (gpointer)(uintptr_t)msg->
id);
2506 static void monitor_retrieve_msg_obj(
struct monitor *monitor,
2510 (gpointer)(uintptr_t)msg->
id);
2511 g_hash_table_remove(monitor->
msg_obj_tab,(gpointer)(uintptr_t)msg->
id);
2527 int buflen,
char *buf,
2529 struct monitor *monitor = NULL;
2536 vwarn(
"could not find monitor for objid %d to get msg_obj_id!\n",
2541 pthread_mutex_unlock(&monitor->
mutex);
2545 msg =
calloc(1,
sizeof(*msg));
2561 if (!msg_obj && objid > 0) {
2564 "could not find obj for objid %d!\n",objid);
2573 #define __M_SAFE_IO(fn,fns,fd,buf,buflen,frc) { \
2577 _p = (char *)(buf); \
2581 (frc) = fn((fd),_p,_left); \
2583 if (errno == EAGAIN || errno == EWOULDBLOCK) { \
2584 goto errout_wouldblock; \
2586 else if (errno != EINTR) { \
2587 vwarn(fns "(%d,%d): %s\n", \
2588 fd,buflen,strerror(errno)); \
2589 goto errout_fatal; \
2592 verror(fns "(%d,%d): %s\n", \
2593 fd,buflen,strerror(errno)); \
2596 else if ((frc) == 0) { \
2597 goto errout_wouldblock; \
2609 unsigned int rc = 0;
2628 __monitor_store_msg_obj(monitor,msg);
2630 len =
sizeof(msg->
objid) +
sizeof(msg->
id) \
2631 +
sizeof(msg->
cmd) +
sizeof(msg->
seqno) +
sizeof(msg->
len);
2640 verror(
"no way to send to thread %lu!\n",monitor->
mtid);
2643 verror(
"no way to send to process %d!\n",monitor->
p.
pid);
2652 rc += (int)
sizeof(msg->
objid);
2656 &msg->
id,(
int)
sizeof(msg->
id),frc);
2657 rc += (int)
sizeof(msg->
id);
2661 &msg->
cmd,(
int)
sizeof(msg->
cmd),frc);
2662 rc += (int)
sizeof(msg->
cmd);
2667 rc += (int)
sizeof(msg->
seqno);
2671 &msg->
len,(
int)
sizeof(msg->
len),frc);
2672 rc += (int)
sizeof(msg->
len);
2681 "sent objid(%d) %d %hd:%hd '%s' (%d)\n",
2684 pthread_mutex_unlock(&monitor->
mutex);
2688 if (rc < len && (errno == EAGAIN || errno == EWOULDBLOCK)) {
2689 verror(
"would have blocked after %d of %d bytes (%d)!\n",rc,len,frc);
2707 if (errno == EPIPE) {
2713 pthread_mutex_unlock(&monitor->
mutex);
2715 monitor_retrieve_msg_obj(monitor,msg);
2725 struct monitor *_monitor = NULL;
2727 len =
sizeof(msg->
objid) +
sizeof(msg->
id) \
2728 +
sizeof(msg->
cmd) +
sizeof(msg->
seqno) +
sizeof(msg->
len);
2733 rc += (int)
sizeof(msg->
objid);
2737 &msg->
id,(
int)
sizeof(msg->
id),frc);
2738 rc += (int)
sizeof(msg->
id);
2742 (
int)
sizeof(msg->
cmd),frc);
2743 rc += (int)
sizeof(msg->
cmd);
2747 (
int)
sizeof(msg->
seqno),frc);
2748 rc += (int)
sizeof(msg->
seqno);
2752 &msg->
len,(
int)
sizeof(msg->
len),frc);
2753 rc += (int)
sizeof(msg->
len);
2767 " objid(%d) %d %hd:%hd '%s' (%d)\n",
2771 if (!__monitor_lookup_objid(msg->
objid,NULL,&obj,&_monitor)) {
2772 vwarn(
"could not find obj for objid %d!\n",msg->
objid);
2778 monitor_retrieve_msg_obj(monitor,msg);
2783 if (rc < len && (errno == EAGAIN || errno == EWOULDBLOCK)) {
2784 verror(
"would have blocked after %d of (at least) %d bytes (%d)!\n",
2786 goto errout_fatal_2;
2790 verror(
"would have blocked after %d of (at least) %d bytes (%d)!\n",
2799 struct monitor *_monitor;
2811 "could not lookup objid %d; deleted?\n",msg->
objid);
2814 else if (_monitor != monitor) {
2815 verror(
"trying to send msg for objid %d on a different monitor!\n",
2819 len =
sizeof(msg->
objid) +
sizeof(msg->
id) \
2820 +
sizeof(msg->
cmd) +
sizeof(msg->
seqno) +
sizeof(msg->
len);
2834 __monitor_store_msg_obj(_monitor,msg);
2841 verror(
"no way to send from monitor thread!\n");
2844 verror(
"no way to send from monitored process!\n");
2853 rc += (int)
sizeof(msg->
objid);
2857 &msg->
id,(
int)
sizeof(msg->
id),frc);
2858 rc += (int)
sizeof(msg->
id);
2862 &msg->
cmd,(
int)
sizeof(msg->
cmd),frc);
2863 rc += (int)
sizeof(msg->
cmd);
2868 rc += (int)
sizeof(msg->
seqno);
2872 &msg->
len,(
int)
sizeof(msg->
len),frc);
2873 rc += (int)
sizeof(msg->
len);
2882 " objid(%d) %d %hd:%hd '%s' (%d)\n",
2885 pthread_mutex_unlock(&_monitor->
mutex);
2889 if (rc < len && (errno == EAGAIN || errno == EWOULDBLOCK)) {
2890 verror(
"would have blocked after %d of %d bytes (BUG) (%d)!\n",rc,len,frc);
2907 verror(
"error after %d of %d bytes: %s (%d)!\n",rc,len,strerror(errno),frc);
2908 pthread_mutex_unlock(&monitor->
mutex);
2910 monitor_retrieve_msg_obj(monitor,msg);
2920 struct monitor *_monitor = NULL;
2922 len =
sizeof(msg->
objid) +
sizeof(msg->
id) \
2923 +
sizeof(msg->
cmd) +
sizeof(msg->
seqno) +
sizeof(msg->
len);
2928 rc += (int)
sizeof(msg->
objid);
2932 &msg->
id,(
int)
sizeof(msg->
id),frc);
2933 rc += (int)
sizeof(msg->
id);
2937 (
int)
sizeof(msg->
cmd),frc);
2938 rc += (int)
sizeof(msg->
cmd);
2942 (
int)
sizeof(msg->
seqno),frc);
2943 rc += (int)
sizeof(msg->
seqno);
2947 &msg->
len,(
int)
sizeof(msg->
len),frc);
2948 rc += (int)
sizeof(msg->
len);
2954 " objid(%d) %d %hd:%hd '%s' (%d)\n",
2961 msg->
msg,(
int)msg->
len,frc);
2966 " objid(%d) %d %hd:%hd '%s' (%d)\n",
2973 if (!__monitor_lookup_objid(msg->
objid,NULL,&obj,&_monitor)) {
2974 vwarn(
"could not find obj for objid %d!\n",msg->
objid);
2981 vwarn(
"received msg len only %d (should be %d) (%d)\n",rc,len,frc);
2983 monitor_retrieve_msg_obj(monitor,msg);
2988 if (rc < len && (errno == EAGAIN || errno == EWOULDBLOCK)) {
2989 verror(
"would have blocked after %d of %d bytes (BUG) (%d)!\n",rc,len,frc);
2990 goto errout_fatal_2;
2994 verror(
"error after %d of %d bytes: %s (%d)!\n",rc,len,strerror(errno),frc);
int monitor_lock_objtype(int objtype)
int monitor_is_done(struct monitor *monitor)
int monitor_objects(struct monitor *monitor)
int waitpipe_add(int pid)
int monitor_get_unique_objid(void)
#define EVLOOP_HRET_REMOVEALLTYPES
#define vwarnopt(level, area, flags, format,...)
int(* monitor_stdio_callback_t)(int fd, char *buf, int len, void *state)
struct monitor_msg * monitor_recv(struct monitor *monitor)
int monitor_run(struct monitor *monitor)
int waitpipe_init_auto(void(*alt_handler)(int, siginfo_t *, void *))
void evloop_free(struct evloop *evloop)
int __monitor_unlock_objtype(int objtype)
int(* close)(struct monitor *monitor, void *obj, void *objstate, int kill, int kill_sig)
struct array_list * monitor_list_objs_by_objtype_lock_objtype(int objtype, int include_null)
int monitor_lookup_obj_lock_monitor(void *obj, int *objtype, int *objid, struct monitor **monitor)
int __safe_write(int fd, char *buf, int count)
static uint64_t unsigned int i
void * stdout_callback_state
int monitor_setup_stderr(struct monitor *monitor, int maxbufsiz, char *stderr_logfile, monitor_stdio_callback_t stderr_callback, void *callback_state)
int monitor_setup_stdin(struct monitor *monitor, char *stdin_buf, int stdin_buflen)
void * stdin_callback_state
int monitor_lookup_obj(void *obj, int *objtype, int *objid, struct monitor **monitor)
int monitor_live_objects(struct monitor *monitor)
int waitpipe_is_initialized(void)
int(* evloop_is_attached)(struct evloop *evloop, void *obj)
int monitor_unlock_objtype(int objtype)
int(* fatal_error)(monitor_error_t error, void *obj)
int evloop_handleone(struct evloop *evloop, evloop_flags_t flags, struct timeval *timeout, struct evloop_fdinfo **handled_fdinfo, int *handled_fdtype, int *handled_hrc)
int monitor_child_send(struct monitor_msg *msg, struct monitor *monitor)
struct monitor_msg * monitor_msg_create(int objid, int id, short cmd, short seqno, int buflen, char *buf, void *msg_obj)
int(* event)(struct monitor *monitor, monitor_event_t event, int objid, void *obj)
int monitor_close_obj(struct monitor *monitor, void *obj, int kill, int kill_sig)
int monitor_del_obj(struct monitor *monitor, void *obj)
int(* evloop_detach)(struct evloop *evloop, void *obj)
#define verror(format,...)
#define EVLOOP_HRET_REMOVETYPE
#define MONITOR_CHILD_RECV_FD_ENVVAR
#define EVLOOP_HRET_DONE_SUCCESS
int monitor_can_attach_bidi(void)
#define vwarn(format,...)
int(* fini)(struct monitor *monitor, void *obj, void *objstate)
#define MONITOR_OBJID_ENVVAR
#define MONITOR_CHILD_SEND_FD_ENVVAR
void monitor_msg_free(struct monitor_msg *msg)
int waitpipe_remove(int pid)
int monitor_lookup_objid_lock_objtype(int objid, int objtype, void **obj, struct monitor **monitor)
int __monitor_child_recv_evh(int fd, int fdtype, void *state)
int __monitor_send_stdin_evh(int fd, int fdtype, void *state)
int(* child_recv_msg)(struct monitor *monitor, struct monitor_msg *msg)
monitor_stdio_callback_t stderr_callback
pthread_mutex_t msg_obj_tab_mutex
int monitor_add_obj(struct monitor *monitor, int objid, int objtype, void *obj, void *objstate)
void monitor_msg_free_save_buffer(struct monitor_msg *msg)
#define vdebug(devel, areas, flags, format,...)
int evloop_set_fd(struct evloop *evloop, int fd, int fdtype, evloop_handler_t handler, void *state)
int(* recv_msg)(struct monitor *monitor, struct monitor_msg *msg)
struct monitor * monitor_attach(monitor_type_t type, monitor_flags_t flags, int objtype, void *obj, void *objstate, evloop_handler_t custom_child_recv_evh, monitor_stdio_callback_t stdin_callback, void *callback_state)
int monitor_add_primary_obj(struct monitor *monitor, int objid, int objtype, void *obj, void *objstate)
int evloop_maxsize(struct evloop *evloop)
int monitor_close_objid(struct monitor *monitor, int objid, int kill, int kill_sig)
#define vdebugc(devel, areas, flags, format,...)
int monitor_live_children(struct monitor *monitor)
void * calloc(size_t nmemb, size_t size)
int unlink(const char *pathname)
int monitor_shutdown(struct monitor *monitor)
struct evloop * evloop_create(evloop_error_handler_t ehandler)
#define EVLOOP_HRET_SUCCESS
monitor_stdio_callback_t stdout_callback
struct array_list * monitor_list_objids_by_objtype_lock_objtype(int objtype, int include_null)
int monitor_can_attach(void)
int monitor_lookup_objid(int objid, int *objtype, void **obj, struct monitor **monitor)
int monitor_unlock_objtype_unsafe(int objtype)
int monitor_lookup_objid_lock_monitor(int objid, int *objtype, void **obj, struct monitor **monitor)
int monitor_spawn(struct monitor *monitor, char *filename, char *const argv[], char *const envp[], char *dir)
int(* evloop_attach)(struct evloop *evloop, void *obj)
struct monitor * monitor_create_custom(monitor_type_t type, monitor_flags_t flags, int objid, int objtype, void *obj, void *objstate, evloop_handler_t custom_recv_evh, evloop_handler_t custom_child_recv_evh)
#define __M_SAFE_IO(fn, fns, fd, buf, buflen, frc)
void * stderr_callback_state
struct monitor * monitor_create(monitor_type_t type, monitor_flags_t flags, int objid, int objtype, void *obj, void *objstate)
#define EVLOOP_HRET_BADERROR
int __monitor_lock_objtype(int objtype)
int monitor_send(struct monitor_msg *msg)
void * malloc(size_t size)
int monitor_del_objid(struct monitor *monitor, int objid)
int __monitor_add_primary_obj(struct monitor *monitor, int objid, int objtype, void *obj, void *objstate)
int vdebug_is_on(int level, log_areas_t areas, log_flags_t flags)
monitor_stdio_callback_t stdin_callback
int monitor_setup_stdout(struct monitor *monitor, int maxbufsiz, char *stdout_logfile, monitor_stdio_callback_t stdout_callback, void *callback_state)
int monitor_destroy(struct monitor *monitor)
int monitor_register_objtype(int objtype, struct monitor_objtype_ops *ops, pthread_mutex_t *mutex)
int(* evloop_handler_t)(int fd, int fdtype, void *state)
void monitor_store_msg_obj(struct monitor *monitor, struct monitor_msg *msg)
int __monitor_recv_evh(int fd, int fdtype, void *state)
int monitor_lookup_objid_lock_objtype_and_monitor(int objid, int objtype, void **obj, struct monitor **monitor)
struct monitor_msg * monitor_child_recv(struct monitor *monitor)