Eclipse SUMO - Simulation of Urban MObility
FXThreadEvent.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2004-2020 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
20 //
21 /****************************************************************************/
22 #include <config.h>
23 
24 #include <fxver.h>
25 #define NOMINMAX
26 #include <xincs.h>
27 #undef NOMINMAX
28 #include <fx.h>
29 #include <utils/common/StdDefs.h>
30 /*
31 #include <fxdefs.h>
32 #include <FXString.h>
33 #include <FXStream.h>
34 #include <FXSize.h>
35 #include <FXPoint.h>
36 #include <FXRectangle.h>
37 #include <FXRegistry.h>
38 #include <FXHash.h>
39 #include <FXApp.h>
40 */
41 #ifndef WIN32
42 #include <unistd.h>
43 #endif
44 
45 using namespace FX;
46 #include "fxexdefs.h"
47 #include "FXThreadEvent.h"
48 
49 // ===========================================================================
50 // used namespaces
51 // ===========================================================================
52 using namespace FXEX;
53 namespace FXEX {
54 
55 #ifndef WIN32
56 # define PIPE_READ 0
57 # define PIPE_WRITE 1
58 #endif
59 
60 // Message map
61 FXDEFMAP(FXThreadEvent) FXThreadEventMap[] = {
62  FXMAPTYPE(0, FXThreadEvent::onThreadEvent),
63  FXMAPFUNC(SEL_THREAD, 0, FXThreadEvent::onThreadEvent),
64  FXMAPFUNC(SEL_IO_READ, FXThreadEvent::ID_THREAD_EVENT, FXThreadEvent::onThreadSignal),
65 };
66 FXIMPLEMENT(FXThreadEvent, FXBaseObject, FXThreadEventMap, ARRAYNUMBER(FXThreadEventMap))
67 
68 // FXThreadEvent : Constructor
69 FXThreadEvent::FXThreadEvent(FXObject* tgt, FXSelector sel) : FXBaseObject(tgt, sel) {
70 #ifndef WIN32
71  FXMALLOC(&event, FXThreadEventHandle, 2);
72  FXint res = pipe(event);
73  FXASSERT(res == 0);
74  UNUSED_PARAMETER(res); // only used for assertion
75  getApp()->addInput(event[PIPE_READ], INPUT_READ, this, ID_THREAD_EVENT);
76 #else
77  event = CreateEvent(nullptr, FALSE, FALSE, nullptr);
78  FXASSERT(event != NULL);
79  getApp()->addInput(event, INPUT_READ, this, ID_THREAD_EVENT);
80 #endif
81 }
82 
83 // ~FXThreadEvent : Destructor
84 FXThreadEvent::~FXThreadEvent() {
85 #ifndef WIN32
86  getApp()->removeInput(event[PIPE_READ], INPUT_READ);
87  ::close(event[PIPE_READ]);
88  ::close(event[PIPE_WRITE]);
89  FXFREE(&event);
90 #else
91  getApp()->removeInput(event, INPUT_READ);
92  ::CloseHandle(event);
93 #endif
94 }
95 
96 // signal the target using the SEL_THREAD seltype
97 // this method is meant to be called from the worker thread
98 void FXThreadEvent::signal() {
99 #ifndef WIN32
100  FXuint seltype = SEL_THREAD;
101  FXint res = ::write(event[PIPE_WRITE], &seltype, sizeof(seltype));
102  UNUSED_PARAMETER(res); // to make the compiler happy
103 #else
104  ::SetEvent(event);
105 #endif
106 }
107 
108 // signal the target using some seltype
109 // this method is meant to be called from the worker thread
110 void FXThreadEvent::signal(FXuint seltype) {
111 #ifndef WIN32
112  FXint res = ::write(event[PIPE_WRITE], &seltype, sizeof(seltype));
113  UNUSED_PARAMETER(res); // to make the compiler happy
114 #else
115  UNUSED_PARAMETER(seltype);
116  ::SetEvent(event);
117 #endif
118 }
119 
120 // this thread is signalled via the IO/event, from other thread.
121 // We also figure out what SEL_type to generate.
122 // We forward it to ourselves first, to allow child classes to handle the event.
123 long FXThreadEvent::onThreadSignal(FXObject*, FXSelector, void*) {
124  FXuint seltype = SEL_THREAD;
125 #ifndef WIN32
126  FXint res = ::read(event[PIPE_READ], &seltype, sizeof(seltype));
127  UNUSED_PARAMETER(res); // to make the compiler happy
128 #else
129  //FIXME need win32 support
130 #endif
131  handle(this, FXSEL(seltype, 0), nullptr);
132  return 0;
133 }
134 
135 // forward thread event to application - we generate the appropriate FOX event
136 // which is now in the main thread (ie no longer in the worker thread)
137 long FXThreadEvent::onThreadEvent(FXObject*, FXSelector sel, void*) {
138  FXuint seltype = FXSELTYPE(sel);
139  return target && target->handle(this, FXSEL(seltype, message), nullptr);
140 }
141 
142 }
143 
144 
145 /****************************************************************************/
#define PIPE_READ
#define PIPE_WRITE
@ ID_THREAD_EVENT
ID for message passing between threads.
Definition: GUIAppEnum.h:292
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:29
FXInputHandle * FXThreadEventHandle
Definition: fxexdefs.h:303
FXDEFMAP(FXThreadEvent) FXThreadEventMap[]
@ SEL_THREAD
Definition: fxexdefs.h:169