-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsh_client.h
More file actions
156 lines (132 loc) · 4.35 KB
/
Copy pathsh_client.h
File metadata and controls
156 lines (132 loc) · 4.35 KB
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
#pragma once
#include <Windows.h>
#include <stdio.h>
#include <stdint.h>
typedef struct sh_client_t sh_client_t;
typedef void (*_sh_client_recv_callback)(sh_client_t* sh, int8_t* buf, uint32_t len);
struct sh_client_t {
HANDLE hBuffer_read;
HANDLE hBuffer_write;
HANDLE hThread_recv;
HANDLE hEvent_read, hEvent_read2;
HANDLE hEvent_write, hEvent_write2;
HANDLE hEvent_exit;
int8_t* buf_read, * buf_write;
size_t buf_len;
uint8_t _active;
_sh_client_recv_callback func_callback;
};
DWORD WINAPI _sh_client_task_recv(void* data) {
sh_client_t* sh = (sh_client_t*)data;
while (sh->_active) {
HANDLE hs[2];
hs[1] = sh->hEvent_read2;
hs[0] = sh->hEvent_exit;
DWORD ret = WaitForMultipleObjects(2, hs, FALSE, INFINITE);
if (ret == WAIT_OBJECT_0) return 0;
uint32_t len = sh->buf_read[0] | (uint32_t)sh->buf_read[1] << 8
| (uint32_t)sh->buf_read[2] << 16 | (uint32_t)sh->buf_read[3] << 24;
int8_t * buf = (int8_t*)malloc(len);
memcpy(buf, &sh->buf_read[4], len);
sh->func_callback(sh, buf, len);
memset(sh->buf_read, 0, sh->buf_len);
SetEvent(sh->hEvent_read);
}
return 0;
}
/*
Sends buffer to sharedmemory-connection
Blocks until buffer read (read flag ist set)
*/
void sh_client_send(sh_client_t * sh, int8_t * buf, uint32_t len) {
if (sh->_active && len + 4 < sh->buf_len) {
HANDLE hs[2];
hs[1] = sh->hEvent_write;
hs[0] = sh->hEvent_exit;
DWORD ret = WaitForMultipleObjects(2, hs, FALSE, INFINITE);
if (ret == WAIT_OBJECT_0) return;
memcpy(&sh->buf_write[4], buf, len);
sh->buf_write[3] = (len >> 24) & 0xFF;
sh->buf_write[2] = (len >> 16) & 0xFF;
sh->buf_write[1] = (len >> 8) & 0xFF;
sh->buf_write[0] = len & 0xFF;
SetEvent(sh->hEvent_write2);
}
}
void sh_client_close(sh_client_t * sh) {
if (!sh) return;
sh->_active = 0;
SetEvent(sh->hEvent_exit);
if (sh->hThread_recv)WaitForSingleObject(sh->hThread_recv, INFINITE);
if (sh->buf_read)UnmapViewOfFile(sh->buf_read);
if (sh->buf_write)UnmapViewOfFile(sh->buf_write);
if (sh->hBuffer_read)CloseHandle(sh->hBuffer_read);
if (sh->hBuffer_write)CloseHandle(sh->hBuffer_write);
if (sh->hEvent_read)CloseHandle(sh->hEvent_read);
if (sh->hEvent_read2)CloseHandle(sh->hEvent_read2);
if (sh->hEvent_write)CloseHandle(sh->hEvent_write);
if (sh->hEvent_write2)CloseHandle(sh->hEvent_write2);
if (sh->hEvent_exit)CloseHandle(sh->hEvent_exit);
free(sh);
}
sh_client_t* sh_client_new(_sh_client_recv_callback callback, const char* shared_name_read, const char* shared_name_write
, const char* event_name_read, const char* event_name_write
, const char* event_name_read2, const char* event_name_write2
, const char* event_name_exit, size_t buf_len) {
sh_client_t* res = (sh_client_t*)malloc(sizeof(sh_client_t));
res->buf_len = buf_len;
res->func_callback = callback;
res->hBuffer_read = CreateFileMapping(INVALID_HANDLE_VALUE,
NULL, PAGE_READWRITE, 0, buf_len, shared_name_read);
if (res->hBuffer_read == NULL) {
goto dispose;
}
res->hBuffer_write = CreateFileMapping(INVALID_HANDLE_VALUE,
NULL, PAGE_READWRITE, 0, buf_len, shared_name_write);
if (res->hBuffer_write == NULL) {
goto dispose;
}
res->buf_read = (int8_t*)MapViewOfFile(res->hBuffer_read, FILE_MAP_ALL_ACCESS,
0, 0, buf_len);
if (res->buf_read == NULL) {
goto dispose;
}
res->buf_write = (int8_t*)MapViewOfFile(res->hBuffer_write, FILE_MAP_ALL_ACCESS,
0, 0, buf_len);
if (res->buf_write == NULL) {
goto dispose;
}
res->hEvent_read = CreateEvent(NULL, FALSE, FALSE, event_name_read);
if (res->hEvent_read == NULL) {
goto dispose;
}
res->hEvent_read2 = CreateEvent(NULL, FALSE, FALSE, event_name_read2);
if (res->hEvent_read2 == NULL) {
goto dispose;
}
res->hEvent_write = CreateEvent(NULL, FALSE, FALSE, event_name_write);
if (res->hEvent_write == NULL) {
goto dispose;
}
res->hEvent_write2 = CreateEvent(NULL, FALSE, FALSE, event_name_write2);
if (res->hEvent_write2 == NULL) {
goto dispose;
}
res->hEvent_exit = CreateEvent(NULL, FALSE, FALSE, event_name_exit);
if (res->hEvent_exit == NULL) {
goto dispose;
}
SetEvent(res->hEvent_write);
SetEvent(res->hEvent_read);
ResetEvent(res->hEvent_write2);
ResetEvent(res->hEvent_read2);
ResetEvent(res->hEvent_exit);
memset(res->buf_read, 0, res->buf_len);
memset(res->buf_write, 0, res->buf_len);
res->_active = 1;
res->hThread_recv = CreateThread(0, 0, _sh_client_task_recv, res, 0, 0);
return res;
dispose:
sh_client_close(res);
return 0;
}