8383#include "utils/guc.h"
8484#include "utils/memutils.h"
8585
86+ #ifdef EMSCRIPTEN
87+ #include <emscripten.h>
88+ #endif
89+
8690/*
8791 * Cope with the various platform-specific ways to spell TCP keepalive socket
8892 * 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);
149153static int internal_putbytes (const char * s , size_t len );
150154static int internal_flush (void );
151155
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+
152163#ifdef HAVE_UNIX_SOCKETS
153164static int Lock_AF_UNIX (const char * unixSocketDir , const char * unixSocketPath );
154165static int Setup_AF_UNIX (const char * sock_path );
155166#endif /* HAVE_UNIX_SOCKETS */
156167
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
157178static const PQcommMethods PqCommSocketMethods = {
158179 socket_comm_reset ,
159180 socket_flush ,
@@ -162,12 +183,91 @@ static const PQcommMethods PqCommSocketMethods = {
162183 socket_putmessage ,
163184 socket_putmessage_noblock
164185};
186+ #endif
165187
166188const PQcommMethods * PqCommMethods = & PqCommSocketMethods ;
167189
168190WaitEventSet * FeBeWaitSet ;
169191
170192
193+ /* --------------------------------
194+ * Emscripten implementation
195+ * --------------------------------
196+ */
197+
198+ #ifdef EMSCRIPTEN
199+ EM_JS (void , emscripten_dispatch_result , (char * res , int len ), {
200+ // Dispatch the result to JS land
201+ if (!Module .eventTarget ) return ;
202+ var heapBytes = new Uint8Array (Module .HEAPU8 .buffer , res , len );
203+ var resultBytes = new Uint8Array (heapBytes );
204+ Module .eventTarget .dispatchEvent (new Module .Event ("result" , {
205+ detail : resultBytes
206+ }));
207+ });
208+ #endif
209+
210+ static void emscripten_comm_reset (void ) {
211+ printf ("emscripten_comm_reset" );
212+ }
213+
214+ static int emscripten_flush (void ) {
215+ printf ("emscripten_flush" );
216+ return 0 ;
217+ }
218+
219+ static int emscripten_flush_if_writable (void ) {
220+ printf ("emscripten_flush_if_writable" );
221+ return 0 ;
222+ }
223+
224+ static bool emscripten_is_send_pending (void ) {
225+ printf ("emscripten_is_send_pending" );
226+ return false;
227+ }
228+
229+ static int emscripten_putmessage (char msgtype , const char * s , size_t len ) {
230+ StringInfoData buf ;
231+ uint32 n32 ;
232+
233+ Assert (msgtype != 0 );
234+
235+ if (PqCommBusy )
236+ return 0 ;
237+ PqCommBusy = true;
238+
239+ // Initialize StringInfoData buffer
240+ initStringInfo (& buf );
241+
242+ // Append msgtype
243+ appendStringInfoChar (& buf , msgtype );
244+
245+ // Calculate message length (len + 4) and convert to network byte order
246+ n32 = pg_hton32 ((uint32 ) (len + 4 ));
247+ // Append length
248+ appendBinaryStringInfo (& buf , (char * ) & n32 , 4 );
249+
250+ // Append actual message
251+ appendBinaryStringInfo (& buf , s , len );
252+
253+ // Dispatch the result
254+ emscripten_dispatch_result (buf .data , buf .len );
255+
256+ // Free StringInfoData buffer memory
257+ pfree (buf .data );
258+
259+ PqCommBusy = false;
260+ return 0 ;
261+
262+ fail :
263+ PqCommBusy = false;
264+ return EOF ;
265+ }
266+
267+ static void emscripten_putmessage_noblock (char msgtype , const char * s , size_t len ) {
268+ emscripten_putmessage (msgtype , s , len );
269+ }
270+
171271/* --------------------------------
172272 * pq_init - initialize libpq at backend startup
173273 * --------------------------------
0 commit comments