void IoThreadPool::stop() { MLOG_MESSAGE(Notice, "stop"); for(boost::ptr_vector<boost::thread>::iterator i = impl_->threads.begin(), end = impl_->threads.end(); i != end; ++i) i->join(); impl_->threads.clear(); MLOG_MESSAGE(Notice, "stop, finished"); }
void PipeNode::handleConnected(const boost::system::error_code & ec, const std::wstring & name) { if(!ec) { MLOG_MESSAGE(Notice, "Pipe connected"); connectDone(); } else if(ec != boost::asio::error::broken_pipe) { MLOG_MESSAGE(Warning, "Listen failed: " << ec << ", " << ec.message()); timer_.expires_from_now(boost::posix_time::milliseconds(250)); timer_.async_wait(boost::bind(&PipeNode::handleExpired, this, _1, boost::protect(boost::bind(&PipeNode::doListen, this, name)))); } }
void Server::startAccept() { MLOG_MESSAGE(Debug, "startAccept()"); nexus::isocket socket(new nexus::Socket(acceptor_.get_io_service())); acceptor_.async_accept(**socket, bindAccept(socket)); }
void Server::start(unsigned short port) { MLOG_MESSAGE(Debug, "start(" << port << ")"); nexus::listen(acceptor_, port); startAccept(); }
bool Connection::processRecord(const FCGIRecord & rec) { MLOG_MESSAGE(Debug, "processRecord(type: " << static_cast<int>(rec.type) << ", len: " << mstd::ntoh(rec.contentLength) << ", request: " << mstd::ntoh(rec.requestId) << ", padding: " << rec.paddingLength << ")"); char * begin = &buffer_[0] + sizeof(rec); switch(rec.type) { case FCGI_BEGIN_REQUEST: { FCGIBeginRequestBody * body = mstd::pointer_cast<FCGIBeginRequestBody*>(begin); keepAlive_ = (body->flags & FCGI_KEEP_CONN) != 0; stream_.clear(); } break; case FCGI_PARAMS: { if(rec.contentLength) stream_.insert(stream_.end(), begin, begin + mstd::ntoh(rec.contentLength)); else { processParams(); stream_.clear(); } } break; case FCGI_STDIN: { if(rec.contentLength) stream_.insert(stream_.end(), begin, begin + mstd::ntoh(rec.contentLength)); else { RequestPtr request(new Request); requestId_ = mstd::ntoh(rec.requestId); request->params.swap(params_); request->body = stream_.empty() ? nexus::Buffer::blank() : nexus::Buffer(&stream_[0], stream_.size()); stream_.clear(); (*socket_)->get_io_service().post(boost::bind(requestHandler_, request, ptr())); if(!keepAlive_) return false; } } break; default: MLOG_MESSAGE(Warning, "Unexpected type: " << static_cast<int>(rec.type)); break; } return true; }
void Server::handleAccept(const boost::system::error_code & ec, const nexus::isocket & socket) { MLOG_MESSAGE(Info, "handleAccept(" << ec << ")"); if(!ec) { MLOG_MESSAGE(Debug, "accepted, local: " << (*socket)->local_endpoint() << ", remote: " << (*socket)->remote_endpoint()); (*socket)->set_option(boost::asio::ip::tcp::no_delay(true)); ConnectionPtr conn = new Connection(socket, handler_); conn->start(); startAccept(); } else { MLOG_MESSAGE(Warning, "Accept failed: " << ec << ", message: " << ec.message()); } }
bool Connection::processRecords() { MLOG_MESSAGE(Debug, "processRecords()"); while(pos_ >= sizeof(FCGIRecord)) { FCGIRecord * rec = mstd::pointer_cast<FCGIRecord*>(&buffer_[0]); size_t recordLen = sizeof(*rec) + mstd::ntoh(rec->contentLength) + rec->paddingLength; if(pos_ >= recordLen) { if(!processRecord(*rec)) return false; memcpy(&buffer_[0], &buffer_[0] + recordLen, pos_ - recordLen); pos_ -= recordLen; } else MLOG_MESSAGE(Debug, "Non full record: " << recordLen); } return true; }
void Connection::handleRead(const boost::system::error_code & ec, size_t bt, const ConnectionPtr & ptr) { MLOG_MESSAGE(Debug, "handleRead(" << ec << ')'); if(!ec) { pos_ += bt; if(processRecords()) startRead(); } }
void Connection::startRead() { MLOG_MESSAGE(Debug, "startRead()"); if(buffer_.size() - pos_ < 0x10000) { buffer_.resize(pos_ + bufferSize); buffer_.resize(buffer_.capacity()); } (*socket_)->async_read_some(boost::asio::buffer(&buffer_[pos_], buffer_.size() - pos_), bindRead(ptr())); }
void Connection::send(const char * begin, const char * end) { MLOG_MESSAGE(Debug, "send(" << requestId_ << ", " << mlog::dump(begin, end) << ")"); const char * prefix = "Content-Type: text/plain\r\n\r\n"; size_t prefixLen = strlen(prefix); size_t len = end - begin + prefixLen; size_t alen = (len + 7) / 8 * 8; RequestId reqId = mstd::hton(requestId_); output_.resize(0x1000); //sizeof(FCGIRecord) + ahlen + sizeof(FCGIRecord) + alen + sizeof(FCGIRecord) + sizeof(FCGIRecord) + sizeof(FCGIEndRequestBody)); char * out = &output_[0]; FCGIRecord * rec = mstd::pointer_cast<FCGIRecord*>(out); rec->version = 1; rec->type = FCGI_STDOUT; rec->requestId = reqId; rec->contentLength = mstd::hton<uint16_t>(len); rec->paddingLength = alen - len; rec->reserved = 0; out += sizeof(*rec); memcpy(out, prefix, prefixLen); out += prefixLen; memcpy(out, begin, end - begin); out += alen - prefixLen; rec = mstd::pointer_cast<FCGIRecord*>(out); rec->version = 1; rec->type = FCGI_STDOUT; rec->requestId = reqId; rec->contentLength = mstd::hton<uint16_t>(0); rec->paddingLength = 0; rec->reserved = 0; out += sizeof(*rec); rec = mstd::pointer_cast<FCGIRecord*>(out); rec->version = 1; rec->type = FCGI_END_REQUEST; rec->requestId = reqId; rec->contentLength = mstd::hton<uint16_t>(sizeof(FCGIEndRequestBody)); rec->paddingLength = 0; rec->reserved = 0; out += sizeof(*rec); FCGIEndRequestBody * body = mstd::pointer_cast<FCGIEndRequestBody*>(out); body->appStatus = mstd::hton<uint32_t>(0); body->protocolStatus = FCGI_REQUEST_COMPLETE; out += sizeof(*body); output_.resize(out - &output_[0]); async_write(**socket_, boost::asio::buffer(output_), bindWrite(ptr())); }
void IoThreadPool::start(size_t count, bool withCurrent) { MLOG_MESSAGE(Notice, "start(" << count << ", " << withCurrent << ")"); if(withCurrent) --count; impl_->threads.reserve(count); while(impl_->threads.size() != count) impl_->threads.push_back(new boost::thread(tracer(logger, Runner(impl_->ioService)))); if(withCurrent) tracer(logger, Runner(impl_->ioService), true)(); }
void Connection::processParams() { MLOG_MESSAGE(Debug, "processParams(" << stream_.size() << ")"); MLOG_MESSAGE(Debug, "processParams(" << mlog::dump(stream_) << ")"); nexus::PacketReader reader(stream_); while(reader.left()) { size_t nameLen = readLen(reader); size_t valueLen = readLen(reader); if(reader.raw() <= reader.end() && nameLen + valueLen <= reader.left()) { std::string name(reader.raw(), reader.raw() + nameLen); reader.skip(nameLen); std::string value(reader.raw(), reader.raw() + valueLen); reader.skip(valueLen); params_.insert(Params::value_type(name, value)); MLOG_MESSAGE(Debug, "param: " << name << ", value: " << value); } else { MLOG_MESSAGE(Error, "left: " << reader.left() << ", nameLen: " << nameLen << ", valueLen: " << valueLen); break; } } }
void run(unsigned short port, const boost::function<void()> & starter, const RequestHandler & handler) { MLOG_MESSAGE(Debug, "run()"); Server server(iotp_->ioService(), handler); starter(); server.start(port); iotp_->start(12); consoleLoop(); server.stop(); iotp_->stop(); }
bool SQLiteStatement::step(ErrorCode & ec) { #if !defined(__APPLE__) && !defined(MLOG_NO_LOGGING) mstd::performance_timer ptimer; #endif int err = sqlite3_step(handle_); #if !defined(__APPLE__) && !defined(MLOG_NO_LOGGING) uint64_t cur = ptimer.microseconds(); if(cur > 100000) MLOG_MESSAGE(Warning, "Slow query: " << cur << ", sql: " << sql_); #endif if(err == SQLITE_ROW) { ec.reset(0, std::string()); return true; } else if(err == SQLITE_DONE) { ec.reset(0, std::string()); return false; } else { resetEC(ec, err, db_.handle()); return false; } }
IoThreadPool::IoThreadPool() : impl_(new Impl) { MLOG_MESSAGE(Notice, "<init>"); }
Connection::~Connection() { MLOG_MESSAGE(Debug, "~Connection()"); }
void Connection::handleWrite(const boost::system::error_code & ec, size_t bytes, const ConnectionPtr & conn) { MLOG_MESSAGE(Debug, "handleWrite(" << ec << ')'); }
IoThreadPool::~IoThreadPool() { MLOG_MESSAGE(Notice, "<done>"); impl_.reset(); MLOG_MESSAGE(Notice, "<done>, finished"); }