24
24
#include <serialosc/serialosc.h>
25
25
#include <serialosc/ipc.h>
26
26
27
- #ifdef _LP64
28
- #define PRIdword "d"
29
- #define PRIudword "u"
30
- #else
31
- #define PRIdword "ld"
32
- #define PRIudword "lu"
33
- #endif
34
-
35
27
static int
36
- recv_msg (struct sosc_state * state , int ipc_fd )
28
+ recv_ipc_msg (struct sosc_state * state , int ipc_fd )
37
29
{
38
30
struct sosc_ipc_msg msg ;
39
31
40
- if (sosc_ipc_msg_read (ipc_fd , & msg ) <= 0 )
32
+ if (sosc_ipc_msg_read (ipc_fd , & msg ) <= 0 ) {
41
33
return 0 ;
34
+ }
42
35
43
36
switch (msg .type ) {
44
37
case SOSC_PROCESS_SHOULD_EXIT :
@@ -50,124 +43,111 @@ recv_msg(struct sosc_state *state, int ipc_fd)
50
43
}
51
44
}
52
45
53
- struct poll_thread_ctx {
54
- struct sosc_state * state ;
55
- HANDLE wakeup_handle ;
56
- };
46
+ int
47
+ wait_for_serial_input (HANDLE hres , LPOVERLAPPED ov , DWORD timeout )
48
+ {
49
+ DWORD event_mask ;
50
+ int result = 0 ;
51
+
52
+ SetCommMask (hres , EV_RXCHAR );
53
+
54
+ if (!WaitCommEvent (hres , & event_mask , ov )) {
55
+ if (GetLastError () == ERROR_IO_PENDING ) {
56
+ switch (WaitForSingleObject (ov -> hEvent , timeout )) {
57
+ case WAIT_OBJECT_0 :
58
+ result = 0 ;
59
+ break ;
60
+ case WAIT_TIMEOUT :
61
+ result = 1 ;
62
+ break ;
63
+ default :
64
+ result = -1 ;
65
+ break ;
66
+ }
67
+ } else {
68
+ result = -1 ;
69
+ }
70
+ } else {
71
+ result = 0 ;
72
+ }
73
+
74
+ return result ;
75
+ }
57
76
58
77
static DWORD WINAPI
59
- stdin_poll_thread (LPVOID _ctx )
78
+ stdin_poll_thread (LPVOID arg )
60
79
{
61
- struct poll_thread_ctx * ctx = _ctx ;
80
+ struct sosc_state * state = arg ;
62
81
63
82
SetConsoleMode (GetStdHandle (STD_INPUT_HANDLE ), ENABLE_PROCESSED_INPUT );
64
83
65
- for (;;) {
66
- recv_msg (ctx -> state , STDIN_FILENO );
67
- SetEvent (ctx -> wakeup_handle );
84
+ while (state -> running ) {
85
+ recv_ipc_msg (state , STDIN_FILENO );
68
86
}
69
87
70
88
return 0 ;
71
89
}
72
90
73
- static bool
74
- wait_for_serial_input ( HANDLE file , LPOVERLAPPED ov )
91
+ static DWORD WINAPI
92
+ serial_poll_thread ( LPVOID arg )
75
93
{
76
- DWORD evt_mask ;
77
-
78
- SetCommMask (file , EV_RXCHAR );
79
-
80
- if (!WaitCommEvent (file , & evt_mask , ov )) {
81
- switch (GetLastError ()) {
82
- case ERROR_IO_PENDING :
83
- break ;
84
- /* evidently we get this when the monome is unplugged? */
85
- case ERROR_ACCESS_DENIED :
86
- return false;
87
- default :
88
- fprintf (stderr , "wait_for_serial_input() error: %" PRIdword "\n" , GetLastError ());
89
- return false;
90
- }
91
- }
92
-
93
- return true;
94
- }
94
+ struct sosc_state * state = arg ;
95
95
96
- int
97
- sosc_event_loop (struct sosc_state * state )
98
- {
99
96
OVERLAPPED ov = {0 , 0 , {{0 , 0 }}};
100
- HANDLE hres , wait_handles [3 ];
101
- WSANETWORKEVENTS network_events ;
102
- struct poll_thread_ctx ctx ;
103
- ssize_t nbytes ;
97
+ ov .hEvent = CreateEvent (NULL , TRUE, FALSE, NULL );
104
98
int status ;
105
99
106
- wait_handles [0 ] = ov .hEvent = CreateEvent (NULL , TRUE, FALSE, NULL );
107
-
108
- wait_handles [1 ] = WSACreateEvent ();
109
- WSAEventSelect (lo_server_get_socket_fd (state -> server ),
110
- wait_handles [1 ], FD_READ );
111
-
112
- wait_handles [2 ] = CreateEvent (NULL , TRUE, FALSE, NULL );
113
-
114
- state -> running = 1 ;
115
-
116
- if (state -> ipc_in_fd > -1 || 1 ) {
117
- ctx .state = state ;
118
- ctx .wakeup_handle = wait_handles [2 ];
119
-
120
- CreateThread (NULL , 0 , stdin_poll_thread , & ctx , 0 , NULL );
121
- }
122
-
123
- hres = (HANDLE ) _get_osfhandle (monome_get_fd (state -> monome ));
124
-
125
- if (!wait_for_serial_input (hres , & ov )) {
126
- return 1 ;
127
- }
100
+ HANDLE monome_handle = (HANDLE ) _get_osfhandle (monome_get_fd (state -> monome ));
128
101
129
102
while (state -> running ) {
130
- switch (WaitForMultipleObjects (3 , wait_handles , FALSE, INFINITE )) {
131
- case WAIT_OBJECT_0 :
103
+ if (wait_for_serial_input (monome_handle , & ov , INFINITE ) == 0 ) {
132
104
do {
133
105
status = monome_event_handle_next (state -> monome );
134
-
135
- if (status < 0 ) {
136
- return 1 ;
137
- }
138
106
} while (status > 0 );
139
107
140
- // reset the event and wait for more input
141
- if (!wait_for_serial_input (hres , & ov )) {
142
- return 1 ;
108
+ if (status < 0 ) {
109
+ goto err ;
143
110
}
111
+ } else {
112
+ goto err ;
113
+ }
114
+ }
144
115
145
- break ;
116
+ err :
117
+ CloseHandle (ov .hEvent );
118
+ return 0 ;
119
+ }
146
120
147
- case WAIT_OBJECT_0 + 1 :
148
- WSAEnumNetworkEvents (lo_server_get_socket_fd (state -> server ),
149
- wait_handles [1 ],
150
- & network_events );
151
- do {
152
- nbytes = lo_server_recv_noblock (state -> server , 0 );
153
- } while (nbytes > 0 );
121
+ static DWORD WINAPI
122
+ osc_poll_thread (LPVOID arg )
123
+ {
124
+ struct sosc_state * state = arg ;
154
125
155
- break ;
126
+ while (state -> running ) {
127
+ lo_server_recv (state -> server );
128
+ }
156
129
157
- case WAIT_OBJECT_0 + 2 :
158
- ResetEvent (wait_handles [2 ]);
159
- break ;
130
+ return 0 ;
131
+ }
160
132
161
- case WAIT_TIMEOUT :
162
- break ;
133
+ int
134
+ sosc_event_loop (struct sosc_state * state )
135
+ {
136
+ HANDLE threads [3 ];
163
137
164
- case WAIT_ABANDONED_0 :
165
- case WAIT_FAILED :
166
- fprintf (stderr , "event_loop(): wait failed: %" PRIdword "\n" ,
167
- GetLastError ());
168
- return 1 ;
169
- }
138
+ state -> running = true;
139
+
140
+ threads [0 ] = CreateThread (NULL , 0 , serial_poll_thread , state , 0 , NULL );
141
+ threads [1 ] = CreateThread (NULL , 0 , osc_poll_thread , state , 0 , NULL );
142
+
143
+ if (state -> ipc_in_fd > -1 ) {
144
+ threads [2 ] = CreateThread (NULL , 0 , stdin_poll_thread , state , 0 , NULL );
145
+ } else {
146
+ // wait for a dummy event if no ipc
147
+ threads [2 ] = CreateEvent (NULL , TRUE, FALSE, NULL );
170
148
}
171
149
150
+ WaitForMultipleObjects (3 , threads , FALSE, INFINITE );
151
+
172
152
return 0 ;
173
153
}
0 commit comments