+
+
+typedef struct KillOtherSessionContext {
+ AsyncIO IO;
+ AsyncIO *OtherOne;
+}KillOtherSessionContext;
+
+eNextState KillTerminate(AsyncIO *IO)
+{
+ long id;
+ KillOtherSessionContext *Ctx = (KillOtherSessionContext*)IO->Data;
+ EV_syslog(LOG_DEBUG, "%s Exit\n", __FUNCTION__);
+ id = IO->ID;
+ FreeAsyncIOContents(IO);
+ memset(Ctx, 0, sizeof(KillOtherSessionContext));
+ IO->ID = id; /* just for the case we want to analyze it in a coredump */
+ free(Ctx);
+ return eAbort;
+
+}
+
+eNextState KillShutdown(AsyncIO *IO)
+{
+ return eTerminateConnection;
+}
+
+eNextState KillOtherContextNow(AsyncIO *IO)
+{
+ KillOtherSessionContext *Ctx = IO->Data;
+
+ SetEVState(IO, eKill);
+
+ if (Ctx->OtherOne->ShutdownAbort != NULL)
+ Ctx->OtherOne->ShutdownAbort(Ctx->OtherOne);
+ return eTerminateConnection;
+}
+
+void KillAsyncIOContext(AsyncIO *IO)
+{
+ KillOtherSessionContext *Ctx;
+
+ Ctx = (KillOtherSessionContext*) malloc(sizeof(KillOtherSessionContext));
+ memset(Ctx, 0, sizeof(KillOtherSessionContext));
+
+ InitIOStruct(&Ctx->IO,
+ Ctx,
+ eReadMessage,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ KillTerminate,
+ NULL,
+ NULL,
+ NULL,
+ KillShutdown);
+
+ Ctx->OtherOne = IO;
+
+ switch(IO->NextState) {
+ case eSendDNSQuery:
+ case eReadDNSReply:
+
+ case eConnect:
+ case eSendReply:
+ case eSendMore:
+ case eSendFile:
+
+ case eReadMessage:
+ case eReadMore:
+ case eReadPayload:
+ case eReadFile:
+ QueueEventContext(&Ctx->IO, KillOtherContextNow);
+ break;
+ case eDBQuery:
+ QueueDBOperation(&Ctx->IO, KillOtherContextNow);
+ break;
+ case eTerminateConnection:
+ case eAbort:
+ /*hm, its already dying, dunno which Queue its in... */
+ free(Ctx);
+ }
+
+}
+
+extern int DebugEventLoopBacktrace;
+void EV_backtrace(AsyncIO *IO)
+{
+#ifdef HAVE_BACKTRACE
+ void *stack_frames[50];
+ size_t size, i;
+ char **strings;
+
+ if ((IO == NULL) || (DebugEventLoopBacktrace == 0))
+ return;
+ size = backtrace(stack_frames, sizeof(stack_frames) / sizeof(void*));
+ strings = backtrace_symbols(stack_frames, size);
+ for (i = 0; i < size; i++) {
+ if (strings != NULL) {
+ EV_syslog(LOG_ALERT, " BT %s\n", strings[i]);
+ }
+ else {
+ EV_syslog(LOG_ALERT, " BT %p\n", stack_frames[i]);
+ }
+ }
+ free(strings);
+#endif
+}
+
+
+ev_tstamp ctdl_ev_now (void)
+{
+ return ev_now(event_base);
+}