{"action":"opened","issue":{"url":"https://api.github.com/repos/shadow/shadow/issues/252","labels_url":"https://api.github.com/repos/shadow/shadow/issues/252/labels{/name}","comments_url":"https://api.github.com/repos/shadow/shadow/issues/252/comments","events_url":"https://api.github.com/repos/shadow/shadow/issues/252/events","html_url":"https://github.com/shadow/shadow/issues/252","id":55038551,"number":252,"title":"some idea about libevent2 deferred callbacks","user":{"login":"vladie","id":10359291,"avatar_url":"https://avatars.githubusercontent.com/u/10359291?v=3","gravatar_id":"","url":"https://api.github.com/users/vladie","html_url":"https://github.com/vladie","followers_url":"https://api.github.com/users/vladie/followers","following_url":"https://api.github.com/users/vladie/following{/other_user}","gists_url":"https://api.github.com/users/vladie/gists{/gist_id}","starred_url":"https://api.github.com/users/vladie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vladie/subscriptions","organizations_url":"https://api.github.com/users/vladie/orgs","repos_url":"https://api.github.com/users/vladie/repos","events_url":"https://api.github.com/users/vladie/events{/privacy}","received_events_url":"https://api.github.com/users/vladie/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2015-01-21T16:06:54Z","updated_at":"2015-01-21T16:06:54Z","closed_at":null,"body":"yesterday i've tried to make simple ping application, which sends tcp-pings every 5 seconds. once i've finished code writing, i've realised that shadow didn't support libevent deferred callbacks (which i create using event_new + event_add). i've studied shadow-tor-plugin and discovered that tor plugin makes per-second calls of tor functions by itself, libevent events not used (because they will work only with event_base_dispatch() endless loop). my idea for solving this problem is to hook event_add:\r\n\r\nstatic void _event_executeCallbackInPluginContext(gpointer data, ShadowPluginCallbackFunc callback)\r\n{\r\n   callback(NULL);\r\n}\r\n\r\nint event_add(struct event *ev, const struct timeval *tv)\r\n{\r\n   int result;\r\n\r\n   ENSURE(libc, \"\", event_add);\r\n\r\n   if (shouldForwardToLibC())\r\n   {\r\n      return director.libc.event_add(ev, tv);\r\n   }\r\n\r\n   Host *node = _interposer_switchInShadowContext();\r\n   if ( tv )\r\n   {\r\n      Thread *thread = worker_getActiveThread();\r\n      if (thread)\r\n      {\r\n         struct _Process *proc = thread_getParentProcess(thread);\r\n        process_callback(proc, (CallbackFunc)_event_executeCallbackInPluginContext, NULL, process_getNotifyFunc(proc), (tv->tv_sec * (uint64_t)1000) + (tv->tv_usec / 1000));\r\n      }\r\n   }\r\n   _interposer_switchOutShadowContext(node);\r\n\r\n   result = director.libc.event_add(ev, tv);\r\n   return result;\r\n}\r\n\r\nin this case, deferred callback will call plugin notify function, which will call event_base_loop(..., EVLOOP_NONBLOCK), which will process event, which was placed in queue by calling original libevent's event_add. this hack works for my sample, but i didn't studied shadow architecture completely yet."}}