9eac713be0f79686c615b6266b95f01ca39d673a
[yazpp-moved-to-github.git] / src / yaz-pdu-assoc-thread.cpp
1 /* This file is part of the yazpp toolkit.
2  * Copyright (C) 1998-2013 Index Data and Mike Taylor
3  * See the file LICENSE for details.
4  */
5
6 #if HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9 #ifdef WIN32
10 #define USE_THREADS 1
11 #endif
12
13 #if YAZ_POSIX_THREADS
14 #define USE_THREADS 1
15 #endif
16
17 #if USE_THREADS
18
19 #if HAVE_UNISTD_H
20 #include <unistd.h>
21 #endif
22
23 #ifdef WIN32
24 #include <process.h>
25 #else
26 #include <pthread.h>
27 #endif
28
29
30 #include <errno.h>
31 #include <yaz/log.h>
32 #include <yaz/tcpip.h>
33
34 #include <yazpp/pdu-assoc.h>
35 #include <yazpp/socket-manager.h>
36
37 using namespace yazpp_1;
38
39 class worker {
40 public:
41     SocketManager *m_mgr;
42     PDU_Assoc *m_assoc;
43     void run();
44 };
45
46 PDU_AssocThread::PDU_AssocThread(
47     ISocketObservable *socketObservable)
48     : PDU_Assoc(socketObservable)
49 {
50
51 }
52
53 PDU_AssocThread::~PDU_AssocThread()
54 {
55
56 }
57
58 void worker::run()
59 {
60     yaz_log (YLOG_LOG, "thread started");
61     while (this->m_mgr->processEvent() > 0)
62         ;
63     yaz_log (YLOG_LOG, "thread finished");
64     delete this->m_mgr;
65     delete this;
66 }
67
68 #ifdef WIN32
69 void __cdecl
70 #else
71 void *
72 #endif
73 events(void *p)
74 {
75     worker *w = (worker *) p;
76     w->run();
77 #ifdef WIN32
78 #else
79     return 0;
80 #endif
81 }
82
83 void PDU_AssocThread::childNotify(COMSTACK cs)
84 {
85     SocketManager *socket_observable = new SocketManager;
86     PDU_Assoc *new_observable = new PDU_Assoc (socket_observable, cs);
87
88     /// Clone PDU Observer
89     new_observable->m_PDU_Observer =
90         m_PDU_Observer->sessionNotify(new_observable, cs_fileno(cs));
91
92     if (!new_observable->m_PDU_Observer)
93     {
94         new_observable->shutdown();
95         delete new_observable;
96         delete socket_observable;
97         return;
98     }
99
100     worker *w = new worker;
101     w->m_assoc = new_observable;
102     w->m_mgr = socket_observable;
103
104 #ifdef WIN32
105     long t_id;
106     t_id = _beginthread (events, 0, w);
107     if (t_id == -1)
108     {
109         yaz_log (YLOG_FATAL|YLOG_ERRNO, "_beginthread failed");
110         exit (1);
111     }
112 #else
113     pthread_t tid;
114
115     int id = pthread_create (&tid, 0, events, w);
116     if (id)
117         yaz_log (YLOG_ERRNO|YLOG_FATAL, "pthread_create returned id=%d", id);
118     else
119         pthread_detach (tid);
120 #endif
121 }
122 #endif
123 /*
124  * Local variables:
125  * c-basic-offset: 4
126  * c-file-style: "Stroustrup"
127  * indent-tabs-mode: nil
128  * End:
129  * vim: shiftwidth=4 tabstop=8 expandtab
130  */
131