83
83
#include "utils/guc.h"
84
84
#include "utils/memutils.h"
85
85
86
+ #ifdef EMSCRIPTEN
87
+ #include <emscripten.h>
88
+ #endif
89
+
86
90
/*
87
91
* Cope with the various platform-specific ways to spell TCP keepalive socket
88
92
* options. This doesn't cover Windows, which as usual does its own thing.
@@ -149,11 +153,28 @@ static void socket_putmessage_noblock(char msgtype, const char *s, size_t len);
149
153
static int internal_putbytes (const char * s , size_t len );
150
154
static int internal_flush (void );
151
155
156
+ static void emscripten_comm_reset (void );
157
+ static int emscripten_flush (void );
158
+ static int emscripten_flush_if_writable (void );
159
+ static bool emscripten_is_send_pending (void );
160
+ static int emscripten_putmessage (char msgtype , const char * s , size_t len );
161
+ static void emscripten_putmessage_noblock (char msgtype , const char * s , size_t len );
162
+
152
163
#ifdef HAVE_UNIX_SOCKETS
153
164
static int Lock_AF_UNIX (const char * unixSocketDir , const char * unixSocketPath );
154
165
static int Setup_AF_UNIX (const char * sock_path );
155
166
#endif /* HAVE_UNIX_SOCKETS */
156
167
168
+ #ifdef EMSCRIPTEN
169
+ static const PQcommMethods PqCommSocketMethods = {
170
+ emscripten_comm_reset ,
171
+ emscripten_flush ,
172
+ emscripten_flush_if_writable ,
173
+ emscripten_is_send_pending ,
174
+ emscripten_putmessage ,
175
+ emscripten_putmessage_noblock
176
+ };
177
+ #else
157
178
static const PQcommMethods PqCommSocketMethods = {
158
179
socket_comm_reset ,
159
180
socket_flush ,
@@ -162,12 +183,97 @@ static const PQcommMethods PqCommSocketMethods = {
162
183
socket_putmessage ,
163
184
socket_putmessage_noblock
164
185
};
186
+ #endif
165
187
166
188
const PQcommMethods * PqCommMethods = & PqCommSocketMethods ;
167
189
168
190
WaitEventSet * FeBeWaitSet ;
169
191
170
192
193
+ /* --------------------------------
194
+ * Emscripten implementation
195
+ * --------------------------------
196
+ */
197
+
198
+ static StringInfoData emscripten_buffer ;
199
+ static bool emscripten_buffer_is_initialized = false;
200
+ static bool emscripten_buffer_busy = false;
201
+
202
+ #ifdef EMSCRIPTEN
203
+ EM_JS (void , emscripten_dispatch_result , (char * res , int len ), {
204
+ // Dispatch the result to JS land
205
+ if (!Module .eventTarget ) return ;
206
+ var heapBytes = new Uint8Array (Module .HEAPU8 .buffer , res , len );
207
+ var resultBytes = new Uint8Array (heapBytes );
208
+ Module .eventTarget .dispatchEvent (new Module .Event ("result" , {
209
+ detail : resultBytes
210
+ }));
211
+ });
212
+ #endif
213
+
214
+ static void emscripten_init_buffer (void ) {
215
+ if (!emscripten_buffer_is_initialized ) {
216
+ initStringInfo (& emscripten_buffer );
217
+ emscripten_buffer_is_initialized = true;
218
+ }
219
+ }
220
+
221
+ static void emscripten_comm_reset (void ) {
222
+ if (emscripten_buffer_is_initialized ) {
223
+ resetStringInfo (& emscripten_buffer );
224
+ } else {
225
+ emscripten_init_buffer ();
226
+ }
227
+ }
228
+
229
+ static int emscripten_flush (void ) {
230
+ if (emscripten_buffer .len > 0 ) {
231
+ emscripten_dispatch_result (emscripten_buffer .data , emscripten_buffer .len );
232
+ resetStringInfo (& emscripten_buffer );
233
+ }
234
+ return 0 ;
235
+ }
236
+
237
+ static int emscripten_flush_if_writable (void ) {
238
+ return emscripten_flush ();
239
+ return 0 ;
240
+ }
241
+
242
+ static bool emscripten_is_send_pending (void ) {
243
+ return emscripten_buffer .len > 0 ;
244
+ }
245
+
246
+ static int emscripten_putmessage (char msgtype , const char * s , size_t len ) {
247
+ if (emscripten_buffer_busy )
248
+ return 0 ;
249
+ emscripten_buffer_busy = true;
250
+
251
+ emscripten_init_buffer ();
252
+
253
+ uint32 n32 ;
254
+ Assert (msgtype != 0 );
255
+
256
+ appendStringInfoChar (& emscripten_buffer , msgtype );
257
+ n32 = pg_hton32 ((uint32 ) (len + 4 ));
258
+ appendBinaryStringInfo (& emscripten_buffer , (char * ) & n32 , 4 );
259
+ appendBinaryStringInfo (& emscripten_buffer , s , len );
260
+
261
+ emscripten_buffer_busy = false;
262
+
263
+ // Flush buffer on every message
264
+ emscripten_flush ();
265
+
266
+ return 0 ;
267
+
268
+ fail :
269
+ emscripten_buffer_busy = false;
270
+ return EOF ;
271
+ }
272
+
273
+ static void emscripten_putmessage_noblock (char msgtype , const char * s , size_t len ) {
274
+ emscripten_putmessage (msgtype , s , len );
275
+ }
276
+
171
277
/* --------------------------------
172
278
* pq_init - initialize libpq at backend startup
173
279
* --------------------------------
0 commit comments