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.
Definition: wvdaemon.h:205
WvLog log
The daemon's log mechanism.
Definition: wvdaemon.h:106
void die(int status=0)
Force the daemon to exit as soon as the run callback exits.
Definition: wvdaemon.h:187
bool want_to_die() const
Whether the daemon will quit when the run callback exits.
Definition: wvdaemon.h:199
void restart()
Force the daemon to restart as soon as the run callback exits.
Definition: wvdaemon.h:182
virtual int geterr() const
If isok() is false, return the system error number corresponding to the error, -1 for a special error...
Definition: wverror.h:48
void runonce(time_t msec_timeout=-1)
Exactly the same as: if (select(timeout)) callback();.
Definition: wvstream.h:391
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.
Definition: wvstring.h:330