From f9e27ff4826983db766f3273641a11498084b616 Mon Sep 17 00:00:00 2001 From: cantor Date: Wed, 20 May 2009 18:23:30 +0000 Subject: [PATCH] https://bugs.internet2.edu/jira/browse/SSPCPP-206 git-svn-id: https://svn.middleware.georgetown.edu/cpp-sp/branches/REL_2@2992 cb58f699-b61c-0410-a6fe-9272a202ed29 --- shibd/shibd.cpp | 13 +++----- shibsp/remoting/ListenerService.h | 15 +++++++++ shibsp/remoting/impl/ListenerService.cpp | 13 +++++--- shibsp/remoting/impl/SocketListener.cpp | 54 ++++++++++++++++---------------- shibsp/remoting/impl/SocketListener.h | 13 +++++--- 5 files changed, 64 insertions(+), 44 deletions(-) diff --git a/shibd/shibd.cpp b/shibd/shibd.cpp index b7a6956..5d18ec1 100644 --- a/shibd/shibd.cpp +++ b/shibd/shibd.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2007 Internet2 + * Copyright 2001-2009 Internet2 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -61,7 +61,7 @@ const char* shar_schemadir = NULL; const char* shar_prefix = NULL; bool shar_checkonly = false; bool shar_version = false; -static int unlink_socket = 0; +static bool unlink_socket = false; const char* pidfile = NULL; #ifdef WIN32 @@ -141,11 +141,9 @@ int real_main(int preinit) //_CrtSetAllocHook(MyAllocHook); - // Run the listener if (!shar_checkonly) { - // Run the listener. - if (!conf.getServiceProvider()->getListenerService()->run(&shibd_shutdown)) { + if (!conf.getServiceProvider()->getListenerService()->run(unlink_socket, &shibd_shutdown)) { fprintf(stderr, "listener failed to enter listen loop\n"); return -3; } @@ -223,7 +221,7 @@ static int parse_args(int argc, char* argv[]) shar_schemadir=optarg; break; case 'f': - unlink_socket = 1; + unlink_socket = true; break; case 't': shar_checkonly=true; @@ -280,7 +278,6 @@ int main(int argc, char *argv[]) if (shar_checkonly) fprintf(stderr, "overall configuration is loadable, check console for non-fatal problems\n"); else { - // Write the pid file if (pidfile) { FILE* pidf = fopen(pidfile, "w"); @@ -293,7 +290,7 @@ int main(int argc, char *argv[]) } // Run the listener - if (!conf.getServiceProvider()->getListenerService()->run(&shibd_shutdown)) { + if (!conf.getServiceProvider()->getListenerService()->run(unlink_socket, &shibd_shutdown)) { fprintf(stderr, "listener failed to enter listen loop\n"); return -3; } diff --git a/shibsp/remoting/ListenerService.h b/shibsp/remoting/ListenerService.h index fcb5eee..8bde279 100644 --- a/shibsp/remoting/ListenerService.h +++ b/shibsp/remoting/ListenerService.h @@ -116,6 +116,7 @@ namespace shibsp { virtual Remoted* lookup(const char* address) const; /** + * @deprecated * OutOfProcess servers can implement server-side transport handling by * calling the run method and supplying a flag to monitor for shutdown. * @@ -124,6 +125,20 @@ namespace shibsp { */ virtual bool run(bool* shutdown)=0; + /** + * OutOfProcess servers can implement server-side transport handling by + * calling the run method and supplying a flag to monitor for shutdown. + * + *

The first parameter applies to implementations that can detect and remove + * the results of ungraceful shutdowns of previous executions and continue + * successfully. File-based sockets are the most common example. + * + * @param force true iff remnant network state should be forcibly cleared + * @param shutdown pointer to flag that caller will set when shutdown is required + * @return true iff the service execution was successful + */ + virtual bool run(bool force, bool* shutdown); + private: std::map m_listenerMap; }; diff --git a/shibsp/remoting/impl/ListenerService.cpp b/shibsp/remoting/impl/ListenerService.cpp index 600c87f..c85c356 100644 --- a/shibsp/remoting/impl/ListenerService.cpp +++ b/shibsp/remoting/impl/ListenerService.cpp @@ -1,6 +1,6 @@ /* - * Copyright 2001-2007 Internet2 - * + * Copyright 2001-2009 Internet2 + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -16,7 +16,7 @@ /** * ListenerService.cpp - * + * * Interprocess remoting engine. */ @@ -93,6 +93,11 @@ void ListenerService::receive(DDF &in, ostream& out) Remoted* dest=lookup(in.name()); if (!dest) throw ListenerException("No destination registered for incoming message addressed to ($1).",params(1,in.name())); - + dest->receive(in, out); } + +bool ListenerService::run(bool force, bool* shutdown) +{ + return run(shutdown); +} diff --git a/shibsp/remoting/impl/SocketListener.cpp b/shibsp/remoting/impl/SocketListener.cpp index 06dd49c..848ed29 100644 --- a/shibsp/remoting/impl/SocketListener.cpp +++ b/shibsp/remoting/impl/SocketListener.cpp @@ -1,6 +1,6 @@ /* * Copyright 2001-2009 Internet2 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -16,7 +16,7 @@ /** * SocketListener.cpp - * + * * Berkeley Socket-based ListenerService implementation */ @@ -45,7 +45,7 @@ using namespace std; using xercesc::DOMElement; namespace shibsp { - + // Manages the pool of connections class SocketPool { @@ -55,16 +55,16 @@ namespace shibsp { ~SocketPool(); SocketListener::ShibSocket get(); void put(SocketListener::ShibSocket s); - + private: SocketListener::ShibSocket connect(); - - Category& m_log; + + Category& m_log; const SocketListener* m_listener; auto_ptr m_lock; stack m_pool; }; - + // Worker threads in server class ServerThread { public: @@ -104,7 +104,7 @@ SocketListener::ShibSocket SocketPool::connect() connected = true; break; } - + m_log.warn("cannot connect socket (%u)...%s", sock, (i > 0 ? "retrying" : "")); if (i) { @@ -179,7 +179,7 @@ SocketListener::~SocketListener() delete m_child_lock; } -bool SocketListener::run(bool* shutdown) +bool SocketListener::run(bool force, bool* shutdown) { #ifdef _DEBUG NDC ndc("run"); @@ -194,7 +194,7 @@ bool SocketListener::run(bool* shutdown) m_catchAll = flag.first && flag.second; } sp->unlock(); - + // Save flag to monitor for shutdown request. m_shutdown=shutdown; unsigned long count = 0; @@ -203,7 +203,7 @@ bool SocketListener::run(bool* shutdown) log->crit("failed to create socket"); return false; } - if (!bind(m_socket,true)) { + if (!bind(m_socket, force)) { this->close(m_socket); log->crit("failed to bind to socket."); return false; @@ -215,7 +215,7 @@ bool SocketListener::run(bool* shutdown) FD_SET(m_socket, &readfds); struct timeval tv = { 0, 0 }; tv.tv_sec = 5; - + switch (select(m_socket + 1, &readfds, 0, 0, &tv)) { #ifdef WIN32 case SOCKET_ERROR: @@ -226,10 +226,10 @@ bool SocketListener::run(bool* shutdown) log_error(); log->error("select() on main listener socket failed"); return false; - + case 0: continue; - + default: { // Accept the connection. @@ -290,7 +290,7 @@ DDF SocketListener::send(const DDF& in) SocketListener::ShibSocket sock; while (retry >= 0) { sock = m_socketpool->get(); - + int outlen = ostr.length(); len = htonl(outlen); if (send(sock,(char*)&len,sizeof(len)) != sizeof(len) || send(sock,ostr.c_str(),outlen) != outlen) { @@ -317,7 +317,7 @@ DDF SocketListener::send(const DDF& in) throw ListenerException("Failure receiving response to remoted message ($1).", params(1,in.name())); } len = ntohl(len); - + char buf[16384]; int size_read; stringstream is; @@ -331,25 +331,25 @@ DDF SocketListener::send(const DDF& in) break; } } - + if (len) { log->error("error reading output message from socket"); this->close(sock); throw ListenerException("Failure receiving response to remoted message ($1).", params(1,in.name())); } - + m_socketpool->put(sock); // Unmarshall data. DDF out; is >> out; - + // Check for exception to unmarshall and throw, otherwise return. if (out.isstring() && out.name() && !strcmp(out.name(),"exception")) { // Reconstitute exception object. DDFJanitor jout(out); XMLToolingException* except=NULL; - try { + try { except=XMLToolingException::fromString(out.string()); log->error("remoted message returned an error: %s", except->what()); } @@ -423,7 +423,7 @@ ServerThread::~ServerThread() m_listener->m_children.erase(m_sock); m_listener->m_child_lock->unlock(); m_listener->m_child_wait->signal(); - + delete m_child; } @@ -437,7 +437,7 @@ void ServerThread::run() m_listener->m_child_wait->wait(m_listener->m_child_lock); m_listener->m_children[m_sock] = m_child; m_listener->m_child_lock->unlock(); - + int result; fd_set readfds; struct timeval tv = { 0, 0 }; @@ -499,19 +499,19 @@ int ServerThread::job() return -1; } len = ntohl(len); - + int size_read; stringstream is; while (len && (size_read = m_listener->recv(m_sock, m_buf, sizeof(m_buf))) > 0) { is.write(m_buf, size_read); len -= size_read; } - + if (len) { log.error("error reading input message from socket"); return -1; } - + // Unmarshall the message. DDF in; DDFJanitor jin(in); @@ -549,7 +549,7 @@ int ServerThread::job() DDFJanitor jout(out); sink << out; } - + // Return whatever's available. string response(sink.str()); int outlen = response.length(); @@ -562,6 +562,6 @@ int ServerThread::job() log.error("error sending output message"); return -1; } - + return 0; } diff --git a/shibsp/remoting/impl/SocketListener.h b/shibsp/remoting/impl/SocketListener.h index 0922cf4..4439927 100644 --- a/shibsp/remoting/impl/SocketListener.h +++ b/shibsp/remoting/impl/SocketListener.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2007 Internet2 + * Copyright 2001-2009 Internet2 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,7 @@ /** * SocketListener.h - * + * * Berkeley Socket-based ListenerService implementation */ @@ -41,7 +41,7 @@ namespace shibsp { class SocketPool; class ServerThread; - + /** * Berkeley Socket-based ListenerService implementation */ @@ -53,7 +53,10 @@ namespace shibsp { ~SocketListener(); DDF send(const DDF& in); - bool run(bool* shutdown); + bool run(bool* shutdown) { + return run(true, shutdown); + } + bool run(bool force, bool* shutdown); // Implemented by socket-specific subclasses. #ifdef WIN32 @@ -74,7 +77,7 @@ namespace shibsp { bool log_error() const; // for OS-level errors xmltooling::logging::Category* log; /// @endcond - + private: mutable SocketPool* m_socketpool; bool* m_shutdown; -- 2.1.4