desktop/debian: moved bsyncjail to pkglibexecdir
[barry/progweb.git] / src / threadwrap.cc
blobffbbf8ea529ea4a23cdf71176093fa50e2e056ea
1 ///
2 /// \file threadwrap.cc
3 /// RAII Wrapper for a single thread.
4 ///
6 /*
7 Copyright (C) 2009, Nicolas VIVIEN
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 See the GNU General Public License in the COPYING file at the
19 root directory of this project for more details.
22 #include "threadwrap.h"
23 #include "error.h"
24 #include <sys/socket.h>
26 namespace Barry {
28 void *callback_wrapper(void *data)
30 Barry::Thread::CallbackData *cbdata = (Barry::Thread::CallbackData*) data;
32 return (*cbdata->callback)(cbdata);
35 Thread::CallbackData::CallbackData(void *userdata)
36 : callback(0)
37 , stopflag(false)
38 , userdata(userdata)
42 Thread::Thread(int socket,
43 void *(*callback)(Barry::Thread::CallbackData *data),
44 void *userdata)
45 : m_socket(socket)
47 m_data = new CallbackData(userdata);
48 m_data->callback = callback;
50 int ret = pthread_create(&thread, NULL, callback_wrapper, m_data);
51 if( ret ) {
52 delete m_data;
53 throw Barry::ErrnoError("Thread: pthread_create failed.", ret);
57 Thread::~Thread()
59 if( pthread_join(thread, NULL) == 0 ) {
60 // successful join, thread is dead, free to free
61 delete m_data;
63 else {
64 // thread is in la-la land, must leak m_data here for safety
68 void Thread::StopFlag()
70 // http://stackoverflow.com/questions/2486335/wake-up-thread-blocked-on-accept-call
72 // set flag first, before waking thread
73 m_data->stopflag = true;
75 // shutdown the socket, but leave the fd valid, thereby waking up
76 // the thread if it is blocked on accept()
77 shutdown(m_socket, SHUT_RDWR);
80 } // namespace Barry