Indents are 8 characters wide and are expressed as a tab character.
[citadel.git] / citadel / event_client.c
index 9b5088f4a0b4931d69e0a91602e2ed92fe39dcd1..1d0fad5429915c8c4b13e9d341a562d7128bacd9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998-2012 by the citadel.org team
+ * Copyright (c) 1998-2017 by the citadel.org team
  *
  * This program is open source software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, version 3.
@@ -26,6 +26,8 @@
 
 #include "ctdl_module.h"
 #include "event_client.h"
+#include "citserver.h"
+#include "config.h"
 
 ConstStr IOStates[] = {
        {HKEY("DB Queue")},
@@ -68,7 +70,7 @@ void SetEVState(AsyncIO *IO, eIOState State)
 
 }
 
-
+eNextState QueueAnEventContext(AsyncIO *IO);
 static void IO_Timeout_callback(struct ev_loop *loop, ev_timer *watcher, int revents);
 static void IO_abort_shutdown_callback(struct ev_loop *loop,
                                       ev_cleanup *watcher,
@@ -86,7 +88,7 @@ extern struct ev_loop *event_db;
 extern ev_async DBAddJob;
 extern ev_async DBExitEventLoop;
 
-eNextState QueueDBOperation(AsyncIO *IO, IO_CallBack CB)
+eNextState QueueAnDBOperation(AsyncIO *IO)
 {
        IOAddHandler *h;
        int i;
@@ -94,7 +96,10 @@ eNextState QueueDBOperation(AsyncIO *IO, IO_CallBack CB)
        SetEVState(IO, eDBQ);
        h = (IOAddHandler*)malloc(sizeof(IOAddHandler));
        h->IO = IO;
-       h->EvAttch = CB;
+
+       assert(IO->ReAttachCB != NULL);
+
+       h->EvAttch = IO->ReAttachCB;
        ev_cleanup_init(&IO->db_abort_by_shutdown,
                        IO_abort_shutdown_callback);
        IO->db_abort_by_shutdown.data = IO;
@@ -104,11 +109,11 @@ eNextState QueueDBOperation(AsyncIO *IO, IO_CallBack CB)
        {
                /* shutting down... */
                free(h);
-               EVM_syslog(LOG_DEBUG, "DBEVENT Q exiting.\n");
+               syslog(LOG_DEBUG, "DBEVENT Q exiting.\n");
                pthread_mutex_unlock(&DBEventQueueMutex);
                return eAbort;
        }
-       EVM_syslog(LOG_DEBUG, "DBEVENT Q\n");
+       syslog(LOG_DEBUG, "DBEVENT Q\n");
        i = ++evdb_count ;
        Put(DBInboundEventQueue, IKEY(i), h, NULL);
        pthread_mutex_unlock(&DBEventQueueMutex);
@@ -122,7 +127,7 @@ eNextState QueueDBOperation(AsyncIO *IO, IO_CallBack CB)
        ev_async_send (event_db, &DBAddJob);
        pthread_mutex_unlock(&DBEventExitQueueMutex);
 
-       EVM_syslog(LOG_DEBUG, "DBEVENT Q Done.\n");
+       syslog(LOG_DEBUG, "DBEVENT Q Done.\n");
        return eDBQuery;
 }
 
@@ -139,7 +144,7 @@ void ShutDownDBCLient(AsyncIO *IO)
        become_session(Ctx);
 
        SetEVState(IO, eDBTerm);
-       EVM_syslog(LOG_DEBUG, "DBEVENT Terminating.\n");
+       syslog(LOG_DEBUG, "DBEVENT Terminating.\n");
        StopDBWatchers(IO);
 
        assert(IO->DBTerminate);
@@ -152,8 +157,8 @@ DB_PerformNext(struct ev_loop *loop, ev_idle *watcher, int revents)
        AsyncIO *IO = watcher->data;
 
        SetEVState(IO, eDBNext);
-       IO->Now = ev_now(event_db);
-       EV_syslog(LOG_DEBUG, "%s()", __FUNCTION__);
+       SET_EV_TIME(IO, event_db);
+       syslog(LOG_DEBUG, "%s()", __FUNCTION__);
        become_session(IO->CitContext);
 
        ev_idle_stop(event_db, &IO->db_unwind_stack);
@@ -161,12 +166,15 @@ DB_PerformNext(struct ev_loop *loop, ev_idle *watcher, int revents)
        assert(IO->NextDBOperation);
        switch (IO->NextDBOperation(IO))
        {
+       case eSendReply:
+               ev_cleanup_stop(loop, &IO->db_abort_by_shutdown);
+               QueueAnEventContext(IO);
+               break;
        case eDBQuery:
                break;
        case eSendDNSQuery:
        case eReadDNSReply:
        case eConnect:
-       case eSendReply:
        case eSendMore:
        case eSendFile:
        case eReadMessage:
@@ -212,14 +220,14 @@ static void IO_abort_shutdown_callback(struct ev_loop *loop,
        AsyncIO *IO = watcher->data;
 
        SetEVState(IO, eIOAbort);
-       EV_syslog(LOG_DEBUG, "EVENT Q: %s\n", __FUNCTION__);
-       IO->Now = ev_now(event_base);
+       syslog(LOG_DEBUG, "EVENT Q: %s\n", __FUNCTION__);
+       SET_EV_TIME(IO, event_base);
        assert(IO->ShutdownAbort);
        IO->ShutdownAbort(IO);
 }
 
 
-eNextState QueueEventContext(AsyncIO *IO, IO_CallBack CB)
+eNextState QueueAnEventContext(AsyncIO *IO)
 {
        IOAddHandler *h;
        int i;
@@ -227,7 +235,11 @@ eNextState QueueEventContext(AsyncIO *IO, IO_CallBack CB)
        SetEVState(IO, eIOQ);
        h = (IOAddHandler*)malloc(sizeof(IOAddHandler));
        h->IO = IO;
-       h->EvAttch = CB;
+
+       assert(IO->ReAttachCB != NULL);
+
+       h->EvAttch = IO->ReAttachCB;
+
        ev_cleanup_init(&IO->abort_by_shutdown,
                        IO_abort_shutdown_callback);
        IO->abort_by_shutdown.data = IO;
@@ -237,11 +249,11 @@ eNextState QueueEventContext(AsyncIO *IO, IO_CallBack CB)
        {
                free(h);
                /* shutting down... */
-               EVM_syslog(LOG_DEBUG, "EVENT Q exiting.\n");
+               syslog(LOG_DEBUG, "EVENT Q exiting.\n");
                pthread_mutex_unlock(&EventQueueMutex);
                return eAbort;
        }
-       EVM_syslog(LOG_DEBUG, "EVENT Q\n");
+       syslog(LOG_DEBUG, "EVENT Q\n");
        i = ++evbase_count;
        Put(InboundEventQueue, IKEY(i), h, NULL);
        pthread_mutex_unlock(&EventQueueMutex);
@@ -253,19 +265,27 @@ eNextState QueueEventContext(AsyncIO *IO, IO_CallBack CB)
        }
        ev_async_send (event_base, &AddJob);
        pthread_mutex_unlock(&EventExitQueueMutex);
-       EVM_syslog(LOG_DEBUG, "EVENT Q Done.\n");
+       syslog(LOG_DEBUG, "EVENT Q Done.\n");
        return eSendReply;
 }
 
-eNextState EventQueueDBOperation(AsyncIO *IO, IO_CallBack CB)
+eNextState EventQueueDBOperation(AsyncIO *IO, IO_CallBack CB, int CloseFDs)
 {
-       StopClientWatchers(IO, 0);
-       return QueueDBOperation(IO, CB);
+       StopClientWatchers(IO, CloseFDs);
+       IO->ReAttachCB = CB;
+       return eDBQuery;
 }
 eNextState DBQueueEventContext(AsyncIO *IO, IO_CallBack CB)
 {
        StopDBWatchers(IO);
-       return QueueEventContext(IO, CB);
+       IO->ReAttachCB = CB;
+       return eSendReply;
+}
+
+eNextState QueueEventContext(AsyncIO *IO, IO_CallBack CB)
+{
+       IO->ReAttachCB = CB;
+       return QueueAnEventContext(IO);
 }
 
 extern eNextState evcurl_handle_start(AsyncIO *IO);
@@ -285,12 +305,12 @@ eNextState QueueCurlContext(AsyncIO *IO)
        {
                /* shutting down... */
                free(h);
-               EVM_syslog(LOG_DEBUG, "EVENT Q exiting.\n");
+               syslog(LOG_DEBUG, "EVENT Q exiting.\n");
                pthread_mutex_unlock(&EventQueueMutex);
                return eAbort;
        }
 
-       EVM_syslog(LOG_DEBUG, "EVENT Q\n");
+       syslog(LOG_DEBUG, "EVENT Q\n");
        i = ++evbase_count;
        Put(InboundEventQueue, IKEY(i), h, NULL);
        pthread_mutex_unlock(&EventQueueMutex);
@@ -303,18 +323,18 @@ eNextState QueueCurlContext(AsyncIO *IO)
        ev_async_send (event_base, &AddJob);
        pthread_mutex_unlock(&EventExitQueueMutex);
 
-       EVM_syslog(LOG_DEBUG, "EVENT Q Done.\n");
+       syslog(LOG_DEBUG, "EVENT Q Done.\n");
        return eSendReply;
 }
 
 eNextState CurlQueueDBOperation(AsyncIO *IO, IO_CallBack CB)
 {
        StopCurlWatchers(IO);
-       return QueueDBOperation(IO, CB);
+       IO->ReAttachCB = CB;
+       return eDBQuery;
 }
 
 
-void DestructCAres(AsyncIO *IO);
 void FreeAsyncIOContents(AsyncIO *IO)
 {
        CitContext *Ctx = IO->CitContext;
@@ -323,8 +343,6 @@ void FreeAsyncIOContents(AsyncIO *IO)
        FreeStrBuf(&IO->SendBuf.Buf);
        FreeStrBuf(&IO->RecvBuf.Buf);
 
-       DestructCAres(IO);
-
        FreeURL(&IO->ConnectMe);
        FreeStrBuf(&IO->HttpReq.ReplyData);
 
@@ -336,8 +354,13 @@ void FreeAsyncIOContents(AsyncIO *IO)
 }
 
 
+void DestructCAres(AsyncIO *IO);
 void StopClientWatchers(AsyncIO *IO, int CloseFD)
 {
+       syslog(LOG_DEBUG, "EVENT StopClientWatchers");
+       
+       DestructCAres(IO);
+
        ev_timer_stop (event_base, &IO->rw_timeout);
        ev_timer_stop(event_base, &IO->conn_fail);
        ev_idle_stop(event_base, &IO->unwind_stack);
@@ -356,7 +379,7 @@ void StopClientWatchers(AsyncIO *IO, int CloseFD)
 
 void StopCurlWatchers(AsyncIO *IO)
 {
-       EVM_syslog(LOG_DEBUG, "EVENT StopCurlWatchers \n");
+       syslog(LOG_DEBUG, "EVENT StopCurlWatchers \n");
 
        ev_timer_stop (event_base, &IO->rw_timeout);
        ev_timer_stop(event_base, &IO->conn_fail);
@@ -377,14 +400,14 @@ void StopCurlWatchers(AsyncIO *IO)
        IO->RecvBuf.fd = 0;
 }
 
-void ShutDownCLient(AsyncIO *IO)
+eNextState ShutDownCLient(AsyncIO *IO)
 {
        CitContext *Ctx =IO->CitContext;
 
        SetEVState(IO, eExit);
        become_session(Ctx);
 
-       EVM_syslog(LOG_DEBUG, "EVENT Terminating \n");
+       syslog(LOG_DEBUG, "EVENT Terminating \n");
 
        StopClientWatchers(IO, 1);
 
@@ -397,11 +420,12 @@ void ShutDownCLient(AsyncIO *IO)
                IO->DNS.Channel = NULL;
        }
        assert(IO->Terminate);
-       IO->Terminate(IO);
+       return IO->Terminate(IO);
 }
 
 void PostInbound(AsyncIO *IO)
 {
+
        switch (IO->NextState) {
        case eSendFile:
                ev_io_start(event_base, &IO->send_event);
@@ -423,6 +447,7 @@ void PostInbound(AsyncIO *IO)
                        break;
                case eDBQuery:
                        StopClientWatchers(IO, 0);
+                       QueueAnDBOperation(IO);
                default:
                        break;
                }
@@ -433,17 +458,18 @@ void PostInbound(AsyncIO *IO)
                ev_io_start(event_base, &IO->recv_event);
                break;
        case eTerminateConnection:
-               ShutDownCLient(IO);
-               break;
        case eAbort:
-               ShutDownCLient(IO);
+               if (ShutDownCLient(IO) == eDBQuery) {
+                       QueueAnDBOperation(IO);
+               }
                break;
        case eSendDNSQuery:
        case eReadDNSReply:
-       case eDBQuery:
        case eConnect:
        case eReadMessage:
                break;
+       case eDBQuery:
+               QueueAnDBOperation(IO);
        }
 }
 eReadState HandleInbound(AsyncIO *IO)
@@ -491,10 +517,17 @@ eReadState HandleInbound(AsyncIO *IO)
                }
 
                if (Finished != eMustReadMore) {
-                       assert(IO->ReadDone);
                        ev_io_stop(event_base, &IO->recv_event);
                        IO->NextState = IO->ReadDone(IO);
-                       Finished = StrBufCheckBuffer(&IO->RecvBuf);
+                       if  (IO->NextState == eDBQuery) {
+                               if (QueueAnDBOperation(IO) == eAbort)
+                                       return eReadFail;
+                               else
+                                       return eReadSuccess;
+                       }
+                       else {
+                               Finished = StrBufCheckBuffer(&IO->RecvBuf);
+                       }
                }
        }
 
@@ -511,7 +544,7 @@ IO_send_callback(struct ev_loop *loop, ev_io *watcher, int revents)
        AsyncIO *IO = watcher->data;
        const char *errmsg = NULL;
 
-       IO->Now = ev_now(event_base);
+       SET_EV_TIME(IO, event_base);
        become_session(IO->CitContext);
 #ifdef BIGBAD_IODBG
        {
@@ -531,6 +564,11 @@ IO_send_callback(struct ev_loop *loop, ev_io *watcher, int revents)
                         IO->SendBuf.fd);
 
                fd = fopen(fn, "a+");
+               if (fd == NULL) {
+                       syslog(LOG_EMERG, "failed to open file %s: %s", fn, strerror(errno));
+                       cit_backtrace();
+                       exit(1);
+               }
                fprintf(fd, "Send: BufSize: %ld BufContent: [",
                        nbytes);
                rv = fwrite(pchh, nbytes, 1, fd);
@@ -635,7 +673,7 @@ IO_send_callback(struct ev_loop *loop, ev_io *watcher, int revents)
        else if (rc < 0) {
                if (errno != EAGAIN) {
                        StopClientWatchers(IO, 1);
-                       EV_syslog(LOG_DEBUG,
+                       syslog(LOG_DEBUG,
                                  "IO_send_callback(): Socket Invalid! [%d] [%s] [%d]\n",
                                  errno, strerror(errno), IO->SendBuf.fd);
                        StrBufPrintf(IO->ErrMsg,
@@ -683,7 +721,7 @@ IO_Timeout_callback(struct ev_loop *loop, ev_timer *watcher, int revents)
        AsyncIO *IO = watcher->data;
 
        SetEVState(IO, eIOTimeout);
-       IO->Now = ev_now(event_base);
+       SET_EV_TIME(IO, event_base);
        ev_timer_stop (event_base, &IO->rw_timeout);
        become_session(IO->CitContext);
 
@@ -712,7 +750,7 @@ IO_connfail_callback(struct ev_loop *loop, ev_timer *watcher, int revents)
        AsyncIO *IO = watcher->data;
 
        SetEVState(IO, eIOConnfail);
-       IO->Now = ev_now(event_base);
+       SET_EV_TIME(IO, event_base);
        ev_timer_stop (event_base, &IO->conn_fail);
 
        if (IO->SendBuf.fd != 0)
@@ -745,7 +783,7 @@ IO_connfailimmediate_callback(struct ev_loop *loop,
        AsyncIO *IO = watcher->data;
 
        SetEVState(IO, eIOConnfailNow);
-       IO->Now = ev_now(event_base);
+       SET_EV_TIME(IO, event_base);
        ev_idle_stop (event_base, &IO->conn_fail_immediate);
 
        if (IO->SendBuf.fd != 0)
@@ -775,8 +813,8 @@ IO_connestd_callback(struct ev_loop *loop, ev_io *watcher, int revents)
         int             err;
 
        SetEVState(IO, eIOConnNow);
-        IO->Now = ev_now(event_base);
-        EVM_syslog(LOG_DEBUG, "connect() succeeded.\n");
+       SET_EV_TIME(IO, event_base);
+        syslog(LOG_DEBUG, "connect() succeeded.\n");
 
         ev_io_stop(loop, &IO->conn_event);
         ev_timer_stop(event_base, &IO->conn_fail);
@@ -789,7 +827,7 @@ IO_connestd_callback(struct ev_loop *loop, ev_io *watcher, int revents)
 
         if ((err == 0) && (so_err != 0))
         {
-                EV_syslog(LOG_DEBUG, "connect() failed [%d][%s]\n",
+                syslog(LOG_DEBUG, "connect() failed [%d][%s]\n",
                           so_err,
                           strerror(so_err));
                 IO_connfail_callback(loop, &IO->conn_fail, revents);
@@ -797,7 +835,7 @@ IO_connestd_callback(struct ev_loop *loop, ev_io *watcher, int revents)
         }
         else
         {
-                EVM_syslog(LOG_DEBUG, "connect() succeeded\n");
+                syslog(LOG_DEBUG, "connect() succeeded\n");
                 set_start_callback(loop, IO, revents);
         }
 }
@@ -809,7 +847,7 @@ IO_recv_callback(struct ev_loop *loop, ev_io *watcher, int revents)
        ssize_t nbytes;
        AsyncIO *IO = watcher->data;
 
-       IO->Now = ev_now(event_base);
+       SET_EV_TIME(IO, event_base);
        switch (IO->NextState) {
        case eReadFile:
                nbytes = FileRecvChunked(&IO->IOB, &errmsg);
@@ -854,6 +892,11 @@ IO_recv_callback(struct ev_loop *loop, ev_io *watcher, int revents)
                         IO->SendBuf.fd);
 
                fd = fopen(fn, "a+");
+               if (fd == NULL) {
+                       syslog(LOG_EMERG, "failed to open file %s: %s", fn, strerror(errno));
+                       cit_backtrace();
+                       exit(1);
+               }
                fprintf(fd, "Read: BufSize: %ld BufContent: [",
                        nbytes);
                rv = fwrite(pchh, nbytes, 1, fd);
@@ -872,7 +915,7 @@ IO_recv_callback(struct ev_loop *loop, ev_io *watcher, int revents)
                if (errno != EAGAIN) {
                        // FD is gone. kick it. 
                        StopClientWatchers(IO, 1);
-                       EV_syslog(LOG_DEBUG,
+                       syslog(LOG_DEBUG,
                                  "IO_recv_callback(): Socket Invalid! [%d] [%s] [%d]\n",
                                  errno, strerror(errno), IO->SendBuf.fd);
                        StrBufPrintf(IO->ErrMsg,
@@ -890,8 +933,8 @@ IO_postdns_callback(struct ev_loop *loop, ev_idle *watcher, int revents)
        AsyncIO *IO = watcher->data;
 
        SetEVState(IO, eCaresFinished);
-       IO->Now = ev_now(event_base);
-       EV_syslog(LOG_DEBUG, "event: %s\n", __FUNCTION__);
+       SET_EV_TIME(IO, event_base);
+       syslog(LOG_DEBUG, "event: %s\n", __FUNCTION__);
        become_session(IO->CitContext);
        assert(IO->DNS.Query->PostDNS);
        switch (IO->DNS.Query->PostDNS(IO))
@@ -902,9 +945,18 @@ IO_postdns_callback(struct ev_loop *loop, ev_idle *watcher, int revents)
                case eAbort:
 ////                   StopClientWatchers(IO);
                        ShutDownCLient(IO);
+                       break;
+               case eDBQuery:
+                       StopClientWatchers(IO, 0);
+                       QueueAnDBOperation(IO);
+                       break;
                default:
                        break;
                }
+       case eDBQuery:
+               StopClientWatchers(IO, 0);
+               QueueAnDBOperation(IO);
+               break;
        default:
                break;
        }
@@ -937,7 +989,7 @@ eNextState EvConnectSock(AsyncIO *IO,
                        IPPROTO_TCP);
 
        if (IO->SendBuf.fd < 0) {
-               EV_syslog(LOG_ERR,
+               syslog(LOG_ERR,
                          "EVENT: socket() failed: %s\n",
                          strerror(errno));
 
@@ -949,7 +1001,7 @@ eNextState EvConnectSock(AsyncIO *IO,
        }
        fdflags = fcntl(IO->SendBuf.fd, F_GETFL);
        if (fdflags < 0) {
-               EV_syslog(LOG_ERR,
+               syslog(LOG_ERR,
                          "EVENT: unable to get socket %d flags! %s \n",
                          IO->SendBuf.fd,
                          strerror(errno));
@@ -963,7 +1015,7 @@ eNextState EvConnectSock(AsyncIO *IO,
        }
        fdflags = fdflags | O_NONBLOCK;
        if (fcntl(IO->SendBuf.fd, F_SETFL, fdflags) < 0) {
-               EV_syslog(
+               syslog(
                        LOG_ERR,
                        "EVENT: unable to set socket %d nonblocking flags! %s \n",
                        IO->SendBuf.fd,
@@ -1008,8 +1060,8 @@ eNextState EvConnectSock(AsyncIO *IO,
        
                memset(&egress_sin, 0, sizeof(egress_sin));
                egress_sin.sin_family = AF_INET;
-               if (!IsEmptyStr(config.c_ip_addr)) {
-                       egress_sin.sin_addr.s_addr = inet_addr(config.c_ip_addr);
+               if (!IsEmptyStr(CtdlGetConfigStr("c_ip_addr"))) {
+                       egress_sin.sin_addr.s_addr = inet_addr(CtdlGetConfigStr("c_ip_addr"));
                        if (egress_sin.sin_addr.s_addr == !INADDR_ANY) {
                                egress_sin.sin_addr.s_addr = INADDR_ANY;
                        }
@@ -1024,13 +1076,13 @@ eNextState EvConnectSock(AsyncIO *IO,
 
        if (rc >= 0){
                SetEVState(IO, eIOConnNow);
-               EV_syslog(LOG_DEBUG, "connect() = %d immediate success.\n", IO->SendBuf.fd);
+               syslog(LOG_DEBUG, "connect() = %d immediate success.\n", IO->SendBuf.fd);
                set_start_callback(event_base, IO, 0);
                return IO->NextState;
        }
        else if (errno == EINPROGRESS) {
                SetEVState(IO, eIOConnWait);
-               EV_syslog(LOG_DEBUG, "connect() = %d have to wait now.\n", IO->SendBuf.fd);
+               syslog(LOG_DEBUG, "connect() = %d have to wait now.\n", IO->SendBuf.fd);
 
                ev_io_init(&IO->conn_event,
                           IO_connestd_callback,
@@ -1050,7 +1102,7 @@ eNextState EvConnectSock(AsyncIO *IO,
                IO->conn_fail_immediate.data = IO;
                ev_idle_start(event_base, &IO->conn_fail_immediate);
 
-               EV_syslog(LOG_ERR,
+               syslog(LOG_ERR,
                          "connect() = %d failed: %s\n",
                          IO->SendBuf.fd,
                          strerror(errno));
@@ -1124,7 +1176,7 @@ void InitIOStruct(AsyncIO *IO,
        IO->SendBuf.Buf   = NewStrBufPlain(NULL, 1024);
        IO->RecvBuf.Buf   = NewStrBufPlain(NULL, 1024);
        IO->IOBuf         = NewStrBuf();
-       EV_syslog(LOG_DEBUG,
+       syslog(LOG_DEBUG,
                  "EVENT: Session lives at %p IO at %p \n",
                  Data, IO);
 
@@ -1168,7 +1220,7 @@ eNextState KillTerminate(AsyncIO *IO)
 {
        long id;
        KillOtherSessionContext *Ctx = (KillOtherSessionContext*)IO->Data;
-       EV_syslog(LOG_DEBUG, "%s Exit\n", __FUNCTION__);
+       syslog(LOG_DEBUG, "%s Exit\n", __FUNCTION__);
        id = IO->ID;
        FreeAsyncIOContents(IO);
        memset(Ctx, 0, sizeof(KillOtherSessionContext));
@@ -1189,8 +1241,13 @@ eNextState KillOtherContextNow(AsyncIO *IO)
 
        SetEVState(IO, eKill);
 
-       if (Ctx->OtherOne->ShutdownAbort != NULL)
-               Ctx->OtherOne->ShutdownAbort(Ctx->OtherOne);
+       if (Ctx->OtherOne->ShutdownAbort != NULL) {
+               Ctx->OtherOne->NextState = eAbort;
+               if (Ctx->OtherOne->ShutdownAbort(Ctx->OtherOne) == eDBQuery) {
+                       StopClientWatchers(Ctx->OtherOne, 0);
+                       QueueAnDBOperation(Ctx->OtherOne);
+               }
+       }
        return eTerminateConnection;
 }
 
@@ -1229,10 +1286,12 @@ void KillAsyncIOContext(AsyncIO *IO)
        case eReadMore:
        case eReadPayload:
        case eReadFile:
-               QueueEventContext(&Ctx->IO, KillOtherContextNow);
+               Ctx->IO.ReAttachCB = KillOtherContextNow;
+               QueueAnEventContext(&Ctx->IO);
                break;
        case eDBQuery:
-               QueueDBOperation(&Ctx->IO, KillOtherContextNow);
+               Ctx->IO.ReAttachCB = KillOtherContextNow;
+               QueueAnDBOperation(&Ctx->IO);
                break;
        case eTerminateConnection:
        case eAbort:
@@ -1256,10 +1315,10 @@ void EV_backtrace(AsyncIO *IO)
        strings = backtrace_symbols(stack_frames, size);
        for (i = 0; i < size; i++) {
                if (strings != NULL) {
-                       EV_syslog(LOG_ALERT, " BT %s\n", strings[i]);
+                       syslog(LOG_ALERT, " BT %s\n", strings[i]);
                }
                else {
-                       EV_syslog(LOG_ALERT, " BT %p\n", stack_frames[i]);
+                       syslog(LOG_ALERT, " BT %p\n", stack_frames[i]);
                }
        }
        free(strings);