Fawkes API  Fawkes Development Version
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
fuse_server.cpp
1 
2 /***************************************************************************
3  * fuse_server.tcp - network image transport server interface
4  *
5  * Generated: Mon Mar 19 15:56:22 2007
6  * Copyright 2005-2007 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version. A runtime exception applies to
14  * this software (see LICENSE.GPL_WRE file mentioned below for details).
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Library General Public License for more details.
20  *
21  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22  */
23 
24 #include <fvutils/net/fuse_server.h>
25 #include <fvutils/net/fuse_server_client_thread.h>
26 
27 #include <core/threading/thread_collector.h>
28 #include <netcomm/utils/acceptor_thread.h>
29 
30 #include <algorithm>
31 
32 using namespace fawkes;
33 
34 namespace firevision {
35 #if 0 /* just to make Emacs auto-indent happy */
36 }
37 #endif
38 
39 /** @class FuseServer <fvutils/net/fuse_server.h>
40  * FireVision FUSE protocol server.
41  * The FuseServer will open a StreamSocket and listen on it for incoming
42  * connections. For each connection a client thread is started that will process
43  * all requests issued by the client.
44  *
45  * @ingroup FUSE
46  * @ingroup FireVision
47  * @author Tim Niemueller
48  */
49 
50 /** Constructor.
51  * @param port Port to listen on for incoming connections
52  * @param collector optional thread collector
53  */
54 FuseServer::FuseServer(unsigned short int port, ThreadCollector *collector)
55  : Thread("FuseServer", Thread::OPMODE_WAITFORWAKEUP)
56 {
57  __thread_collector = collector;
58 
59  __acceptor_thread = new NetworkAcceptorThread(this, port, "FuseNetworkAcceptorThread");
60  if (__thread_collector) {
61  __thread_collector->add(__acceptor_thread);
62  } else {
63  __acceptor_thread->start();
64  }
65 }
66 
67 
68 /** Destructor. */
70 {
71  if ( __thread_collector ) {
72  __thread_collector->remove(__acceptor_thread);
73  } else {
74  __acceptor_thread->cancel();
75  __acceptor_thread->join();
76  }
77 
78  for (__cit = __clients.begin(); __cit != __clients.end(); ++__cit) {
79  if ( __thread_collector ) {
80  // ThreadCollector::remove also stops the threads!
81  __thread_collector->remove(*__cit);
82  } else {
83  (*__cit)->cancel();
84  (*__cit)->join();
85  }
86  delete *__cit;
87  }
88  __clients.clear();
89 
90  delete __acceptor_thread;
91 }
92 
93 
94 void
96 {
97  FuseServerClientThread *client = new FuseServerClientThread(this, s);
98  if ( __thread_collector) {
99  __thread_collector->add(client);
100  } else {
101  client->start();
102  }
103  __clients.push_back_locked(client);
104 }
105 
106 
107 /** Connection died.
108  * @param client client whose connection died
109  */
110 void
112 {
113  __dead_clients.push_back_locked(client);
114  wakeup();
115 }
116 
117 
118 void
120 {
121  // Check for dead clients, cancel and join if there are any
122  __dead_clients.lock();
123  __clients.lock();
124 
126 
127  while ( ! __dead_clients.empty() ) {
128  dcit = __dead_clients.begin();
129 
130  if ( __thread_collector ) {
131  // ThreadCollector::remove also stops the threads!
132  __thread_collector->remove(*dcit);
133  } else {
134  (*dcit)->cancel();
135  (*dcit)->join();
136  }
137  if ( (__cit = find(__clients.begin(), __clients.end(), *dcit)) != __clients.end() ) {
138  __clients.erase(__cit);
139  }
140 
141  FuseServerClientThread *tc = *dcit;
142  __dead_clients.erase(dcit);
143  delete tc;
144  }
145 
146  __clients.unlock();
147  __dead_clients.unlock();
148 }
149 
150 } // end namespace firevision
virtual void loop()
Code to execute in the thread.
void connection_died(FuseServerClientThread *client)
Connection died.
Network Acceptor Thread.
virtual void remove(ThreadList &tl)=0
Remove multiple threads.
Thread collector.
Thread class encapsulation of pthreads.
Definition: thread.h:42
TCP stream socket over IP.
Definition: stream.h:31
List with a lock.
Definition: thread.h:40
virtual void add(ThreadList &tl)=0
Add multiple threads.
void cancel()
Cancel a thread.
Definition: thread.cpp:640
void join()
Join the thread.
Definition: thread.cpp:599
virtual void add_connection(fawkes::StreamSocket *s)
Add an incoming connection.
Definition: fuse_server.cpp:95
virtual ~FuseServer()
Destructor.
Definition: fuse_server.cpp:69
void start(bool wait=true)
Call this method to start the thread.
Definition: thread.cpp:507