WvStreams
wvstreamsdaemon.cc
1/* -*- Mode: C++ -*-
2 * Worldvisions Tunnel Vision Software:
3 * Copyright (C) 1997-2005 Net Integration Technologies, Inc.
4 *
5 * High-level abstraction for creating daemon processes that do
6 * nothing but listen on a list of WvStreams and add connections
7 * to the global list.
8 */
9
10#include "wvstreamsdaemon.h"
11
12#ifndef _WIN32
13#include <signal.h>
14#endif
15
16void WvStreamsDaemon::init(WvDaemonCallback cb)
17{
18 do_full_close = false;
19 setcallback(cb);
20#ifndef _WIN32
21 signal(SIGPIPE, SIG_IGN);
22#endif
23}
24
25void WvStreamsDaemon::do_start()
26{
27 WvDaemon::do_start();
28
29 callback();
30}
31
32void WvStreamsDaemon::do_run()
33{
34 if (streams.isempty())
35 {
36 log(WvLog::Error, "No streams; exiting\n");
37 die();
38 }
39
40 while (should_run())
41 {
42 WvDaemon::do_run();
43 WvIStreamList::globallist.runonce();
44 }
45}
46
47void WvStreamsDaemon::do_stop()
48{
49 WvIStreamList::Iter stream(streams);
50 for (stream.rewind(); stream.next(); )
51 WvIStreamList::globallist.unlink(stream.ptr());
52 streams.zap();
53 if (do_full_close || want_to_die())
54 WvIStreamList::globallist.zap();
55
56 WvDaemon::do_stop();
57}
58
60 bool autofree, const char *id)
61{
62 streams.append(istream, false, id);
63 // FIXME: we should pass in "id" here, but things are not happy in
64 // const-correctness-land.
65 WvIStreamList::globallist.append(istream, autofree, id);
66}
67
69 const char *id)
70{
71 add_stream(istream, autofree, id);
72
73 istream->setclosecallback(wv::bind(&WvStreamsDaemon::restart_close_cb,
74 this, istream, id));
75}
76
78 bool autofree, const char *id)
79{
80 add_stream(istream, autofree, id);
81
82 istream->setclosecallback(wv::bind(&WvStreamsDaemon::die_close_cb, this,
83 istream, id));
84}
85
86void WvStreamsDaemon::restart_close_cb(IWvStream *s, const char *id)
87{
88 if (should_run())
89 {
90 WvString err = s->geterr() ? s->errstr() : "no error";
91 log(WvLog::Error, "%s is closed (%s); restarting\n",
92 id ? id : "Stream", err);
93 restart();
94 }
95}
96
97void WvStreamsDaemon::die_close_cb(IWvStream *s, const char *id)
98{
99 if (should_run())
100 {
101 WvString err = s->geterr() ? s->errstr() : "no error";
102 log(WvLog::Error, "%s is closed (%s); dying\n",
103 id ? id : "Stream", err);
104 die();
105 }
106}
107
108void WvStreamsDaemon::setcallback(WvDaemonCallback cb)
109{
110 callback = cb;
111}
112
virtual IWvStreamCallback setclosecallback(IWvStreamCallback _callfunc)=0
Sets a callback to be invoked on close().
bool should_run() const
Whether the daemon should continue runnning.
void die(int status=0)
Force the daemon to exit as soon as the run callback exits.
bool want_to_die() const
Whether the daemon will quit when the run callback exits.
void restart()
Force the daemon to restart as soon as the run callback exits.
virtual int geterr() const
If isok() is false, return the system error number corresponding to the error, -1 for a special error...
void runonce(time_t msec_timeout=-1)
Exactly the same as: if (select(timeout)) callback();.
void setcallback(WvDaemonCallback cb)
Change the callback function and userdata.
void add_restart_stream(IWvStream *istream, bool auto_free, const char *id)
Add a stream to the daemon; the daemon will restart, re-populating the initial streams using the call...
void add_die_stream(IWvStream *istream, bool auto_free, const char *id)
Add a stream to the daemon; if the stream goes !isok() the daemon will exit.
void add_stream(IWvStream *istream, bool auto_free, const char *id)
Add a stream to the daemon; don't do anything if it goes !isok().
WvString is an implementation of a simple and efficient printable-string class.