From: <bni...@us...> - 2006-12-12 21:35:53
|
Revision: 423 http://svn.sourceforge.net/omc/?rev=423&view=rev Author: bnicholes Date: 2006-12-12 13:35:53 -0800 (Tue, 12 Dec 2006) Log Message: ----------- Realign the socket interaction of the server so that all of the data input is detected by the select call rather than the getline function. Modified Paths: -------------- clp/trunk/src/omcclpc.cpp clp/trunk/src/omcclpdsvrconnection.cpp Modified: clp/trunk/src/omcclpc.cpp =================================================================== --- clp/trunk/src/omcclpc.cpp 2006-12-12 21:33:29 UTC (rev 422) +++ clp/trunk/src/omcclpc.cpp 2006-12-12 21:35:53 UTC (rev 423) @@ -440,7 +440,7 @@ bool runOnce = false; String histFile = getenv ("HOME"); String prompt; - char lineBuf[1024]; + char lineBuf[4096]; /* Get the timout value from the configuration file. */ String item = getConfigItem(OMCClpdConfigOpts::SERVER_TIMEOUT_opt, @@ -587,7 +587,7 @@ /* Read the data from the socket and parse it on carriage returns. */ memset(lineBuf, 0, sizeof(lineBuf)); - int bytesRead = m_socket.read(lineBuf, sizeof(lineBuf)); + int bytesRead = m_socket.read(lineBuf, sizeof(lineBuf)-1); /* If we got data back then process it. Otherwise consider it to be an EOF and bail out. */ Modified: clp/trunk/src/omcclpdsvrconnection.cpp =================================================================== --- clp/trunk/src/omcclpdsvrconnection.cpp 2006-12-12 21:33:29 UTC (rev 422) +++ clp/trunk/src/omcclpdsvrconnection.cpp 2006-12-12 21:35:53 UTC (rev 423) @@ -61,37 +61,37 @@ ////////////////////////////////////////////////////////////////////////////// OMCClpdSvrConnection::OMCClpdSvrConnection(const Socket& socket, - OMCClpdServer* pServer, - IntrusiveReference<UnnamedPipe>& upipe) - : Runnable() - , m_pServer(pServer) - , m_socket(socket) - , m_upipe(upipe) - , m_shutdown(false) + OMCClpdServer* pServer, + IntrusiveReference<UnnamedPipe>& upipe) + : Runnable() + , m_pServer(pServer) + , m_socket(socket) + , m_upipe(upipe) + , m_shutdown(false) , m_clpSession() { - OW_LOG_DEBUG(pServer->getEnv()->getLogger(COMPONENT_NAME), - "OMCClpdSvrConnection object created"); + OW_LOG_DEBUG(pServer->getEnv()->getLogger(COMPONENT_NAME), + "OMCClpdSvrConnection object created"); - String item = pServer->getEnv()->getConfigItem( - OMCClpdConfigOpts::SERVER_TIMEOUT_opt, OMCCLPD_DEFAULT_SERVER_TIMEOUT); - m_socket.setTimeouts(item.toInt32()); + String item = pServer->getEnv()->getConfigItem( + OMCClpdConfigOpts::SERVER_TIMEOUT_opt, OMCCLPD_DEFAULT_SERVER_TIMEOUT); + m_socket.setTimeouts(item.toInt32()); } ////////////////////////////////////////////////////////////////////////////// // Destructor OMCClpdSvrConnection::~OMCClpdSvrConnection() { - try - { - m_socket.disconnect(); - } - catch (...) - { - // don't let exceptions escape - } + try + { + m_socket.disconnect(); + } + catch (...) + { + // don't let exceptions escape + } - OW_LOG_DEBUG(m_pServer->getEnv()->getLogger(COMPONENT_NAME), - "OMCClpdSvrConnection object destroyed"); + OW_LOG_DEBUG(m_pServer->getEnv()->getLogger(COMPONENT_NAME), + "OMCClpdSvrConnection object destroyed"); } ////////////////////////////////////////////////////////////////////////////// @@ -101,55 +101,52 @@ { String bfr; - if (is) - { - size_t count = 0; - std::streambuf *sb = is.rdbuf(); - - while (1) - { - int ch = sb->sbumpc(); - if (ch == EOF) - { - is.setstate(count == 0 - ? (std::ios::failbit | std::ios::eofbit) : std::ios::eofbit); - break; - } - - ++count; - - if ((ch == '\n') || (ch == '\r')) - { - break; - } + if (is) + { + std::streambuf *sb = is.rdbuf(); + sb->sgetc(); + std::streamsize count = sb->in_avail(); + bool stopReading = false; - bfr += String((char)ch); - } - } + /* Since the CLP will only allow a single command before + responding, read a line up to the \n or \r and then + empty the buffer to make sure that the server + stays insync with the client. */ + while (count-- > 0) + { + int ch = sb->sbumpc(); + + if ((ch == '\n') || (ch == '\r')) + stopReading = true; - return bfr; + if (!stopReading) + bfr += String((char)ch); + } + } + + return bfr; } ////////////////////////////////////////////////////////////////////////////// void OMCClpdSvrConnection::run() { - LoggerRef logger = m_pServer->getEnv()->getLogger(COMPONENT_NAME); + LoggerRef logger = m_pServer->getEnv()->getLogger(COMPONENT_NAME); - OW_LOG_DEBUG(logger, "OMCClpdSvrConnection::run entered"); + OW_LOG_DEBUG(logger, "OMCClpdSvrConnection::run entered"); - SelectTypeArray selArray; - selArray.push_back(m_upipe->getSelectObj()); - selArray.push_back(m_socket.getSelectObj()); + SelectTypeArray selArray; + selArray.push_back(m_upipe->getSelectObj()); + selArray.push_back(m_socket.getSelectObj()); - // Get input & output streams from socket - std::istream& sistr(m_socket.getInputStream()); - std::ostream& sostr(m_socket.getOutputStream()); + // Get input & output streams from socket + std::istream& sistr(m_socket.getInputStream()); + std::ostream& sostr(m_socket.getOutputStream()); - // Get timeout value - String item = m_pServer->getEnv()->getConfigItem( - OMCClpdConfigOpts::SERVER_TIMEOUT_opt, OMCCLPD_DEFAULT_SERVER_TIMEOUT); - Int32 timeout = item.toInt32(); + // Get timeout value + String item = m_pServer->getEnv()->getConfigItem( + OMCClpdConfigOpts::SERVER_TIMEOUT_opt, OMCCLPD_DEFAULT_SERVER_TIMEOUT); + Int32 timeout = item.toInt32(); OMCCLPProgramRef clpref(new OMCCLPDaemon(sostr)); clpref->setLogger(logger); @@ -158,105 +155,89 @@ { setCLPSession(clpref); - try - { - bool firstLine = true; + try + { + String line; - while (sistr.good()) - { - if (!firstLine) - { - String line = getLine(sistr); - OW_LOG_DEBUG(logger, - Format("OMCClpdSvrConnection received line: %1", line)); + while (sistr.good()) + { + line.erase(); - if (!line.empty()) { - clpref->runCommand(line); - sostr.flush(); - } - - if (clpref->shouldExit()) - { - line = "Good-bye :-)"; - sostr << line << "\r\n"; - sostr.flush(); - break; - } - } - else - firstLine = false; - /* Send the prompt to the client */ sostr << "\r\n"CLPPROMPT; sostr.flush(); - - // only select if the buffer is empty - if (sistr.rdbuf()->in_avail() == 0) - { - int selType = Select::SELECT_INTERRUPTED; - while(selType == Select::SELECT_INTERRUPTED) - { - selType = Select::select(selArray, timeout * 1000); // *1000 to convert seconds to milliseconds - } - - if (selType == Select::SELECT_ERROR) - { - OW_THROW(SocketException, "Error occurred during select()"); - } - if (selType == Select::SELECT_TIMEOUT) - { - OW_LOG_INFO(logger, "Client connection timed out"); - return; - } - if (selType == 0) // Unnamped pipe/event selected - { - OW_LOG_DEBUG(logger, "Server is shutting down. Closing connection"); - return; - } - } - else - { - // check for server shutting down message. - int selType = Select::select(selArray, 0); // 0 so we don't block - if (selType == 0) // Unnamped pipe/event selected - { - OW_LOG_DEBUG(logger, - "Server is shutting down. Closing connection"); - return; - } - } - } // while (sistr.good()) + int selType = Select::SELECT_INTERRUPTED; + while(selType == Select::SELECT_INTERRUPTED) + { + selType = Select::select(selArray, timeout * 1000); // *1000 to convert seconds to milliseconds + } + + if (selType == Select::SELECT_ERROR) + { + OW_THROW(SocketException, "Error occurred during select()"); + } + if (selType == Select::SELECT_TIMEOUT) + { + OW_LOG_INFO(logger, "Client connection timed out"); + break; + } + if (selType == 0) // Unnamped pipe/event selected + { + OW_LOG_DEBUG(logger, "Server is shutting down. Closing connection"); + break; + } + else if (selType == 1) + { + line = getLine(sistr); + } + + if (line.length()) { + OW_LOG_DEBUG(logger, + Format("OMCClpdSvrConnection received line: %1", line)); + clpref->runCommand(line); + sostr.flush(); + } + + if (clpref->shouldExit()) + { + line = "Good-bye :-)"; + sostr << line << "\r\n"; + sostr.flush(); + break; + } + } // while (sistr.good()) + clpref->destroyCLPSessionInfo(); - } // try - catch (Exception& e) - { - OW_LOG_ERROR(logger, Format("%1", e)); - } - catch (std::ios_base::failure& e) - { - // This happens if the socket is closed, so we don't - //have to do anything. - OW_LOG_DEBUG(logger, "Caught std::ios_base::failure, " - "client has closed the connection"); - } - catch (std::exception& e) - { - OW_LOG_ERROR(logger, Format("Caught std::exception (%1) " - "in OMCClpdSvrConnection::run()", e.what())); - } - catch (ThreadCancelledException&) - { - OW_LOG_ERROR(logger, "Got Thread Cancelled Exception in " - "OMCClpdSvrConnection::run()"); - throw; - } - catch (...) - { - OW_LOG_ERROR(logger, "Got Unknown Exception in " - "OMCClpdSvrConnection::run()"); - } + } // try + catch (Exception& e) + { + OW_LOG_ERROR(logger, Format("%1", e)); + } + catch (std::ios_base::failure& e) + { + // This happens if the socket is closed, so we don't + //have to do anything. + OW_LOG_DEBUG(logger, "Caught std::ios_base::failure, " + "client has closed the connection"); + } + catch (std::exception& e) + { + OW_LOG_ERROR(logger, Format("Caught std::exception (%1) " + "in OMCClpdSvrConnection::run()", e.what())); + } + catch (ThreadCancelledException&) + { + OW_LOG_ERROR(logger, "Got Thread Cancelled Exception in " + "OMCClpdSvrConnection::run()"); + throw; + } + catch (...) + { + OW_LOG_ERROR(logger, "Got Unknown Exception in " + "OMCClpdSvrConnection::run()"); + } } else { @@ -264,23 +245,23 @@ "OMCClpdSvrConnection::run()"); } - OW_LOG_DEBUG(logger, "OMCClpdSvrConnection::run exiting"); + OW_LOG_DEBUG(logger, "OMCClpdSvrConnection::run exiting"); } ////////////////////////////////////////////////////////////////////////////// String OMCClpdSvrConnection::getHostName() { - //return m_socket.getLocalAddress().getName(); - return SocketAddress::getAnyLocalHost().getName(); + //return m_socket.getLocalAddress().getName(); + return SocketAddress::getAnyLocalHost().getName(); } ////////////////////////////////////////////////////////////////////////////// void OMCClpdSvrConnection::doCooperativeCancel() { - m_shutdown = true; - m_socket.disconnect(); + m_shutdown = true; + m_socket.disconnect(); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |