File: FXReactor.h

package info (click to toggle)
gogglesmm 1.2.5-6
  • links: PTS
  • area: main
  • in suites: forky, sid
  • size: 16,812 kB
  • sloc: cpp: 231,960; ansic: 893; xml: 222; makefile: 33
file content (157 lines) | stat: -rw-r--r-- 6,359 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/********************************************************************************
*                                                                               *
*                            R e a c t o r   C l a s s                          *
*                                                                               *
*********************************************************************************
* Copyright (C) 2006,2022 by Jeroen van der Zijp.   All Rights Reserved.        *
*********************************************************************************
* This library is free software; you can redistribute it and/or modify          *
* it under the terms of the GNU Lesser General Public License as published by   *
* the Free Software Foundation; either version 3 of the License, or             *
* (at your option) any later version.                                           *
*                                                                               *
* This library is distributed in the hope that it will be useful,               *
* but WITHOUT ANY WARRANTY; without even the implied warranty of                *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                 *
* GNU Lesser General Public License for more details.                           *
*                                                                               *
* You should have received a copy of the GNU Lesser General Public License      *
* along with this program.  If not, see <http://www.gnu.org/licenses/>          *
********************************************************************************/
#ifndef FXREACTOR_H
#define FXREACTOR_H

namespace FX {


/**
* FXReactor implements the reactor pattern.
* Given a list of file descriptors (handles), calling thread is blocked until
* any of the following happens:
*
*   - One or more of the file descriptors becomes active;
*   - A timeout occurs;
*   - The maximum blocking time is exceeded;
*   - An interrupt (signal) occurs.
*   - One or more of the handles develops an error and an FXFatalException
*     is thrown.
*
* Depending on what occurred, FXReactor dispatches to one of the handling
* API's: dispatchHandle(), dispatchTimeout(), or dispatchSignal().
* Prior to blocking, if nothing demands immediate attention, the special
* handler dispatchIdle() is called.
*
* If dispatchHandle(), dispatchTimeout(), dispatchSignal() or dispatchIdle()
* returned true, FXReactor will return with true; otherwise, it will continue
* to loop, decreasing the initial blocking time until eventually returning false
* when nothing happened during the entire blocking interval.
*
* Each FXReactor can manage a set of signals, but note that only one single
* FXReactor is allowed to manage a particular signal; other signals may be
* left unassigned, or managed by other FXReactors.
*
* If waiting for a very long but finite amount of time, FXReactor will wake up
* after at most FXReactor::maxwait, which is about 1 day.
* It will continue to loop and wait for additional intervals, decreasing the initial
* blocking time until eventually returning false when nothing happened.
*/
class FXAPI FXReactor {
  friend class FXEventDispatcher;
private:
  struct Internals;
private:
  Internals      *internals;            // Internals
  FXint           sigreceived;          // Most recent received signal
  FXint           numhandles;           // Number of handles
  FXint           numwatched;           // Number of watched
  FXint           numraised;            // Number of raised handles
  FXint           current;              // Current handle
private:
  static FXReactor* volatile sigmanager[64];
private:
  FXReactor(const FXReactor&);
  FXReactor &operator=(const FXReactor&);
private:
  static void CDECL signalhandler(FXint sig);
  static void CDECL signalhandlerasync(FXint sig);
public:

  /// Modes
  enum {
    InputNone   = 0,                    /// Inactive handle
    InputRead   = 1,                    /// Read input handle
    InputWrite  = 2,                    /// Write input handle
    InputExcept = 4                     /// Except input handle
    };

  /// Dispatch flags
  enum {
    DispatchAll     = 0xffffffff,       /// Dispatch all events
    DispatchSignals = 0x00000001,       /// Dispatch signals
    DispatchTimers  = 0x00000002,       /// Dispatch timers
    DispatchIdle    = 0x00000004,       /// Dispatch idle processing
    DispatchEvents  = 0x00000008,       /// Dispatch events
    DispatchOther   = 0x00000010        /// Dispatch other i/o
    };

  /// Sleep no longer than this
  static const FXTime maxwait;

public:

  /// Construct reactor.
  FXReactor();

  /// Initialize reactor.
  virtual FXbool init();

  /// Is reactor initialized.
  FXbool isInitialized() const { return (internals!=nullptr); }

  /// Dispatch if something happens within given blocking time.
  /// Flags control subsets of events to be dispatched (signals, timers,
  /// idle, and more). Default is to dispatch all events.
  virtual FXbool dispatch(FXTime blocking=forever,FXuint flags=DispatchAll);

  /// Add new handle hnd to watch-list
  virtual FXbool addHandle(FXInputHandle hnd,FXuint mode=InputRead);

  /// Remove handle hnd from watch-list
  virtual FXbool remHandle(FXInputHandle hnd);

  /// Dispatch handler for handle hnd.
  /// Return true if the callback returned true.
  virtual FXbool dispatchHandle(FXInputHandle hnd,FXuint mode,FXuint flags);

  /// Add (optionally asynchronous) signal sig to signal-set
  virtual FXbool addSignal(FXint sig,FXbool=false);

  /// Remove signal sig from signal-set
  virtual FXbool remSignal(FXint sig);

  /// Return true if signal sig is handled by this dispatcher.
  virtual FXbool hasSignal(FXint sig) const;

  /// Dispatch when a signal was fired; return true when handled.
  virtual FXbool dispatchSignal(FXint sig);

  /// Return time when first timer callback is due; the special
  /// value forever is returned when no timer is in effect.
  virtual FXTime nextTimeout();

  /// Dispatch when timeout expires; return true when handled.
  virtual FXbool dispatchTimeout(FXTime due);

  /// Dispatch when idle; return true when handled.
  virtual FXbool dispatchIdle();

  /// Exit reactor.
  virtual FXbool exit();

  /// Destroy reactor object.
  virtual ~FXReactor();
  };

}

#endif