WvStreams
|
00001 /* -*- Mode: C++ -*- 00002 * Worldvisions Tunnel Vision Software: 00003 * Copyright (C) 1997-2005 Net Integration Technologies, Inc. 00004 * 00005 * High-level abstraction for creating daemon processes that do 00006 * nothing but listen on a list of WvStreams and add connections 00007 * to the global list. 00008 */ 00009 00010 #include "wvstreamsdaemon.h" 00011 00012 #ifndef _WIN32 00013 #include <signal.h> 00014 #endif 00015 00016 void WvStreamsDaemon::init(WvDaemonCallback cb) 00017 { 00018 do_full_close = false; 00019 setcallback(cb); 00020 #ifndef _WIN32 00021 signal(SIGPIPE, SIG_IGN); 00022 #endif 00023 } 00024 00025 void WvStreamsDaemon::do_start() 00026 { 00027 WvDaemon::do_start(); 00028 00029 callback(); 00030 } 00031 00032 void WvStreamsDaemon::do_run() 00033 { 00034 if (streams.isempty()) 00035 { 00036 log(WvLog::Error, "No streams; exiting\n"); 00037 die(); 00038 } 00039 00040 while (should_run()) 00041 { 00042 WvDaemon::do_run(); 00043 WvIStreamList::globallist.runonce(); 00044 } 00045 } 00046 00047 void WvStreamsDaemon::do_stop() 00048 { 00049 WvIStreamList::Iter stream(streams); 00050 for (stream.rewind(); stream.next(); ) 00051 WvIStreamList::globallist.unlink(stream.ptr()); 00052 streams.zap(); 00053 if (do_full_close || want_to_die()) 00054 WvIStreamList::globallist.zap(); 00055 00056 WvDaemon::do_stop(); 00057 } 00058 00059 void WvStreamsDaemon::add_stream(IWvStream *istream, 00060 bool autofree, const char *id) 00061 { 00062 streams.append(istream, false, id); 00063 // FIXME: we should pass in "id" here, but things are not happy in 00064 // const-correctness-land. 00065 WvIStreamList::globallist.append(istream, autofree, id); 00066 } 00067 00068 void WvStreamsDaemon::add_restart_stream(IWvStream *istream, bool autofree, 00069 const char *id) 00070 { 00071 add_stream(istream, autofree, id); 00072 00073 istream->setclosecallback(wv::bind(&WvStreamsDaemon::restart_close_cb, 00074 this, istream, id)); 00075 } 00076 00077 void WvStreamsDaemon::add_die_stream(IWvStream *istream, 00078 bool autofree, const char *id) 00079 { 00080 add_stream(istream, autofree, id); 00081 00082 istream->setclosecallback(wv::bind(&WvStreamsDaemon::die_close_cb, this, 00083 istream, id)); 00084 } 00085 00086 void WvStreamsDaemon::restart_close_cb(IWvStream *s, const char *id) 00087 { 00088 if (should_run()) 00089 { 00090 WvString err = s->geterr() ? s->errstr() : "no error"; 00091 log(WvLog::Error, "%s is closed (%s); restarting\n", 00092 id ? id : "Stream", err); 00093 restart(); 00094 } 00095 } 00096 00097 void WvStreamsDaemon::die_close_cb(IWvStream *s, const char *id) 00098 { 00099 if (should_run()) 00100 { 00101 WvString err = s->geterr() ? s->errstr() : "no error"; 00102 log(WvLog::Error, "%s is closed (%s); dying\n", 00103 id ? id : "Stream", err); 00104 die(); 00105 } 00106 } 00107 00108 void WvStreamsDaemon::setcallback(WvDaemonCallback cb) 00109 { 00110 callback = cb; 00111 } 00112