Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2004-2024 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 : /****************************************************************************/
14 : /// @file MFXThreadEvent.cpp
15 : /// @author Mathew Robertson
16 : /// @author Daniel Krajzewicz
17 : /// @author Michael Behrisch
18 : /// @date 2004-03-19
19 : ///
20 : //
21 : /****************************************************************************/
22 : #include <config.h>
23 :
24 : #define NOMINMAX
25 : #undef NOMINMAX
26 : #include "fxheader.h"
27 : #include <utils/common/StdDefs.h>
28 : /*
29 : #include <fxdefs.h>
30 : #include <FXString.h>
31 : #include <FXStream.h>
32 : #include <FXSize.h>
33 : #include <FXPoint.h>
34 : #include <FXRectangle.h>
35 : #include <FXRegistry.h>
36 : #include <FXHash.h>
37 : #include <FXApp.h>
38 : */
39 : #ifndef WIN32
40 : #include <unistd.h>
41 : #endif
42 :
43 : using namespace FX;
44 : #include "MFXThreadEvent.h"
45 :
46 : // ===========================================================================
47 : // used namespaces
48 : // ===========================================================================
49 : using namespace FXEX;
50 : namespace FXEX {
51 :
52 : #ifndef WIN32
53 : # define PIPE_READ 0
54 : # define PIPE_WRITE 1
55 : #endif
56 :
57 : // Message map
58 : FXDEFMAP(MFXThreadEvent) MFXThreadEventMap[] = {
59 : FXMAPTYPE(0, MFXThreadEvent::onThreadEvent),
60 : FXMAPFUNC(SEL_THREAD, 0, MFXThreadEvent::onThreadEvent),
61 : FXMAPFUNC(SEL_IO_READ, MFXThreadEvent::ID_THREAD_EVENT, MFXThreadEvent::onThreadSignal),
62 : };
63 9816262 : FXIMPLEMENT(MFXThreadEvent, MFXBaseObject, MFXThreadEventMap, ARRAYNUMBER(MFXThreadEventMap))
64 :
65 : // MFXThreadEvent : Constructor
66 15102 : MFXThreadEvent::MFXThreadEvent(FXObject* tgt, FXSelector sel) : MFXBaseObject(tgt, sel) {
67 : #ifndef WIN32
68 15102 : FXMALLOC(&event, MFXThreadEventHandle, 2);
69 15102 : FXint res = pipe(event);
70 : FXASSERT(res == 0);
71 : UNUSED_PARAMETER(res); // only used for assertion
72 15102 : getApp()->addInput(event[PIPE_READ], INPUT_READ, this, ID_THREAD_EVENT);
73 : #else
74 : event = CreateEvent(nullptr, FALSE, FALSE, nullptr);
75 : FXASSERT(event != NULL);
76 : getApp()->addInput(event, INPUT_READ, this, ID_THREAD_EVENT);
77 : #endif
78 15102 : }
79 :
80 : // ~MFXThreadEvent : Destructor
81 15076 : MFXThreadEvent::~MFXThreadEvent() {
82 : #ifndef WIN32
83 15076 : getApp()->removeInput(event[PIPE_READ], INPUT_READ);
84 15076 : ::close(event[PIPE_READ]);
85 15076 : ::close(event[PIPE_WRITE]);
86 15076 : FXFREE(&event);
87 : #else
88 : getApp()->removeInput(event, INPUT_READ);
89 : ::CloseHandle(event);
90 : #endif
91 15076 : }
92 :
93 : // signal the target using the SEL_THREAD seltype
94 : // this method is meant to be called from the worker thread
95 5919992 : void MFXThreadEvent::signal() {
96 : #ifndef WIN32
97 5919992 : FXuint seltype = SEL_THREAD;
98 5919992 : FXint res = ::write(event[PIPE_WRITE], &seltype, sizeof(seltype));
99 : UNUSED_PARAMETER(res); // to make the compiler happy
100 : #else
101 : ::SetEvent(event);
102 : #endif
103 5919992 : }
104 :
105 : // signal the target using some seltype
106 : // this method is meant to be called from the worker thread
107 0 : void MFXThreadEvent::signal(FXuint seltype) {
108 : #ifndef WIN32
109 0 : FXint res = ::write(event[PIPE_WRITE], &seltype, sizeof(seltype));
110 : UNUSED_PARAMETER(res); // to make the compiler happy
111 : #else
112 : UNUSED_PARAMETER(seltype);
113 : ::SetEvent(event);
114 : #endif
115 0 : }
116 :
117 : // this thread is signalled via the IO/event, from other thread.
118 : // We also figure out what SEL_type to generate.
119 : // We forward it to ourselves first, to allow child classes to handle the event.
120 4908131 : long MFXThreadEvent::onThreadSignal(FXObject*, FXSelector, void*) {
121 4908131 : FXuint seltype = SEL_THREAD;
122 : #ifndef WIN32
123 4908131 : FXint res = ::read(event[PIPE_READ], &seltype, sizeof(seltype));
124 : UNUSED_PARAMETER(res); // to make the compiler happy
125 : #else
126 : //FIXME need win32 support
127 : #endif
128 4908131 : handle(this, FXSEL(seltype, 0), nullptr);
129 4908131 : return 0;
130 : }
131 :
132 : // forward thread event to application - we generate the appropriate FOX event
133 : // which is now in the main thread (ie no longer in the worker thread)
134 4908131 : long MFXThreadEvent::onThreadEvent(FXObject*, FXSelector sel, void*) {
135 : FXuint seltype = FXSELTYPE(sel);
136 4908131 : return target && target->handle(this, FXSEL(seltype, message), nullptr);
137 : }
138 :
139 : }
140 :
141 :
142 : /****************************************************************************/
|