diff --git a/src/Command.cpp b/src/Command.cpp index a61d286..0b5df05 100644 --- a/src/Command.cpp +++ b/src/Command.cpp @@ -19,6 +19,7 @@ const Command Command::CmdPool[Sentinel] = { {AuthServ, "auth", 2, 2, Inner}, {Select, "select", 2, 2, Read}, {SelectServ, "select", 2, 2, Inner}, + {Quit, "quit", 1, MaxArgs, Read}, {SentinelSentinels, "sentinel sentinels",3, 3, Inner}, {SentinelGetMaster, "sentinel get-m-a..",3, 3, Inner}, {SentinelSlaves, "sentinel slaves", 3, 3, Inner}, diff --git a/src/Command.h b/src/Command.h index a6e5b61..eb15709 100644 --- a/src/Command.h +++ b/src/Command.h @@ -25,6 +25,7 @@ public: AuthServ, Select, SelectServ, + Quit, SentinelSentinels, SentinelGetMaster, diff --git a/src/Connection.cpp b/src/Connection.cpp index 51daf69..40c6de2 100644 --- a/src/Connection.cpp +++ b/src/Connection.cpp @@ -9,7 +9,8 @@ Connection::Connection(): mPostEvts(0), mBufCnt(0), - mDb(0) + mDb(0), + mCloseASAP(false) { } diff --git a/src/Connection.h b/src/Connection.h index 6ec6df3..1ea343b 100644 --- a/src/Connection.h +++ b/src/Connection.h @@ -29,6 +29,14 @@ public: }; public: Connection(); + void closeASAP() + { + mCloseASAP = true; + } + bool isCloseASAP() const + { + return mCloseASAP; + } int getPostEvent() const { return mPostEvts; @@ -56,6 +64,7 @@ private: BufferPtr mBuf; int mBufCnt; int mDb; + bool mCloseASAP; }; #endif diff --git a/src/Handler.cpp b/src/Handler.cpp index e3cc6b2..a969a5f 100644 --- a/src/Handler.cpp +++ b/src/Handler.cpp @@ -166,11 +166,14 @@ void Handler::postAcceptConnectionEvent() bool ret; if (finished) { ret = mEventLoop->delEvent(c, Multiplexor::WriteEvent); + if (c->isCloseASAP()) { + c->setStatus(AcceptConnection::None); + } } else { ret = mEventLoop->addEvent(c, Multiplexor::WriteEvent); } if (!ret) { - c->setStatus(Multiplexor::ErrorEvent); + c->setStatus(AcceptConnection::IOError); } } } @@ -460,7 +463,7 @@ void Handler::handleRequest(Request* req) { FuncCallTimer(); auto c = req->connection(); - if (c && c->isBlockRequest()) { + if (c && (c->isBlockRequest() || c->isCloseASAP())) { return; } ++mStats.requests; @@ -550,6 +553,12 @@ bool Handler::preHandleRequest(Request* req, const String& key) directResponse(req, Response::InvalidDb); } return true; + case Command::Quit: + directResponse(req, Response::Ok); + if (c) { + c->closeASAP(); + } + return true; case Command::Cmd: directResponse(req, Response::Cmd); return true; diff --git a/src/RequestParser.cpp b/src/RequestParser.cpp index 8fb7fbf..a01db85 100644 --- a/src/RequestParser.cpp +++ b/src/RequestParser.cpp @@ -469,6 +469,7 @@ void RequestParser::parseCmd() case Command::Echo: case Command::Auth: case Command::Select: + case Command::Quit: break; default: mStatus = CmdError;