Skip to content

Remove asyncify #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/backend/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ ifneq ($(PORTNAME), win32)
ifneq ($(PORTNAME), aix)

postgres: $(OBJS)
$(CC) $(CFLAGS) $(call expand_subsys,$^) $(LDFLAGS) $(LDFLAGS_EX) $(export_dynamic) $(LIBS) -s FORCE_FILESYSTEM=1 -s ASYNCIFY=1 -lnodefs.js -lproxyfs.js -lidbfs.js -o $@
$(CC) $(CFLAGS) $(call expand_subsys,$^) $(LDFLAGS) $(LDFLAGS_EX) $(export_dynamic) $(LIBS) -sALLOW_MEMORY_GROWTH=1 -sFORCE_FILESYSTEM=1 -lnodefs.js -lproxyfs.js -lidbfs.js -o $@

endif
endif
endif
Expand Down
171 changes: 95 additions & 76 deletions src/backend/tcop/postgres.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,14 @@ static void log_disconnections(int code, Datum arg);
static void enable_statement_timeout(void);
static void disable_statement_timeout(void);

/* ----------------------------------------------------------------
* decls for PGlite routines
* ----------------------------------------------------------------
*/
static void PostgresMain_Part0(void);
static void PostgresMain_Part1(void);
static void PostgresMain_Part2(void);
extern void ExecProtocolMsg(char *query);

/* ----------------------------------------------------------------
* routines to obtain user input
Expand Down Expand Up @@ -335,51 +343,6 @@ interactive_getc(void)
return c;
}

/* ----------------
* EmscriptenBackend()
*
* ----------------
*/

#ifdef EMSCRIPTEN
EM_ASYNC_JS(char *, await_query, (), {
// Await a query from JS land
Module.eventTarget.dispatchEvent(new Module.Event("waiting"));
var query = await new Promise((resolve, reject) => {
Module.eventTarget.addEventListener("query", (e) => {
resolve(e.detail);
}, {once: true});
});
// `query` is a Uint8Array containing the query in pg wire format
var bytes = query.length;
var ptr = _malloc(bytes);
Module.HEAPU8.set(query, ptr);
return ptr;
});
#endif

static int
EmscriptenBackend(StringInfo inBuf)
{
char *query = await_query();
char qtype = *query; // First byte is qtype

int32 msgLen = *((int32 *)(query + 1)); // Next 4 bytes are message length
msgLen = pg_ntoh32(msgLen);
int dataLen = msgLen - 4; // The rest of the message is the data

resetStringInfo(inBuf);
if (dataLen > 0)
{
// Append the data to the buffer
appendBinaryStringInfo(inBuf, query + 5, dataLen);
}

free(query);

return qtype;
}

/* ----------------
* SocketBackend() Is called for frontend-backend connections
*
Expand Down Expand Up @@ -522,11 +485,7 @@ ReadCommand(StringInfo inBuf)
int result;

if (whereToSendOutput == DestRemote)
#ifdef EMSCRIPTEN
result = EmscriptenBackend(inBuf);
#else
result = SocketBackend(inBuf);
#endif
else
result = InteractiveBackend(inBuf);
return result;
Expand Down Expand Up @@ -3974,6 +3933,58 @@ process_postgres_switches(int argc, char *argv[], GucContext ctx,
}


/* ----------------------------------------------------------------
* ExecProtocolMsg
* PGlite main execute protocol message
* ----------------------------------------------------------------
*/

int firstchar;
StringInfoData input_message;
sigjmp_buf local_sigjmp_buf;
volatile bool send_ready_for_query = true;
bool idle_in_transaction_timeout_enabled = false;
bool idle_session_timeout_enabled = false;

extern void
ExecProtocolMsg(char *query)
{
char qtype = *query; // First byte is qtype

int32 msgLen = *((int32 *)(query + 1)); // Next 4 bytes are message length
msgLen = pg_ntoh32(msgLen);
int dataLen = msgLen - 4; // The rest of the message is the data

resetStringInfo(&input_message);
if (dataLen > 0)
{
// Append the data to the buffer
appendBinaryStringInfo(&input_message, query + 5, dataLen);
}

firstchar = qtype;
free(query);

/* Setup error handling */
if (sigsetjmp(local_sigjmp_buf, 1) != 0)
{
PostgresMain_Part0();

/* We can now handle ereport(ERROR) */
PG_exception_stack = &local_sigjmp_buf;

if (!ignore_till_sync)
send_ready_for_query = true; /* initially, or after error */

return; // Return to the caller
}

/* Process the query */
PostgresMain_Part2();
PostgresMain_Part1();
}


/* ----------------------------------------------------------------
* PostgresMain
* postgres main loop -- all backends, interactive or otherwise start here
Expand All @@ -3983,20 +3994,20 @@ process_postgres_switches(int argc, char *argv[], GucContext ctx,
* dbname is the name of the database to connect to, or NULL if the database
* name should be extracted from the command line arguments or defaulted.
* username is the PostgreSQL user name to be used for the session.
*
* Mods:
*
* This has been modified to be called from PGlite and exits early once
* initialisation is complete.
* ExecProtocolMsg above is called to process the query.
* ----------------------------------------------------------------
*/

void
PostgresMain(int argc, char *argv[],
const char *dbname,
const char *username)
{
int firstchar;
StringInfoData input_message;
sigjmp_buf local_sigjmp_buf;
volatile bool send_ready_for_query = true;
bool idle_in_transaction_timeout_enabled = false;
bool idle_session_timeout_enabled = false;

/* Initialize startup process environment if necessary. */
if (!IsUnderPostmaster)
InitStandaloneProcess(argv[0]);
Expand Down Expand Up @@ -4245,9 +4256,27 @@ PostgresMain(int argc, char *argv[],
* unblock in AbortTransaction() because the latter is only called if we
* were inside a transaction.
*/

if (sigsetjmp(local_sigjmp_buf, 1) != 0)
{
PostgresMain_Part0();
}

/* We can now handle ereport(ERROR) */
PG_exception_stack = &local_sigjmp_buf;

if (!ignore_till_sync)
send_ready_for_query = true; /* initially, or after error */

/*
* Non-error queries loop here.
*/
PostgresMain_Part1();
exit(0);
}

void
PostgresMain_Part0()
{
/*
* NOTE: if you are tempted to add more code in this if-block,
* consider the high probability that it should be in
Expand Down Expand Up @@ -4350,20 +4379,11 @@ PostgresMain(int argc, char *argv[],

/* Now we can allow interrupts again */
RESUME_INTERRUPTS();
}

/* We can now handle ereport(ERROR) */
PG_exception_stack = &local_sigjmp_buf;

if (!ignore_till_sync)
send_ready_for_query = true; /* initially, or after error */

/*
* Non-error queries loop here.
*/
}

for (;;)
{
void
PostgresMain_Part1()
{
/*
* At top of loop, reset extended-query-message flag, so that any
* errors encountered in "idle" state don't provoke skip.
Expand Down Expand Up @@ -4470,12 +4490,12 @@ PostgresMain(int argc, char *argv[],
* STDIN doing the same thing.)
*/
DoingCommandRead = true;
}

/*
* (3) read a command (loop blocks here)
*/
firstchar = ReadCommand(&input_message);

void
PostgresMain_Part2()
{
/*
* (4) turn off the idle-in-transaction and idle-session timeouts, if
* active. We do this before step (5) so that any last-moment timeout
Expand Down Expand Up @@ -4522,7 +4542,7 @@ PostgresMain(int argc, char *argv[],
* Sync.
*/
if (ignore_till_sync && firstchar != EOF)
continue;
return;

switch (firstchar)
{
Expand Down Expand Up @@ -4775,7 +4795,6 @@ PostgresMain(int argc, char *argv[],
errmsg("invalid frontend message type %d",
firstchar)));
}
} /* end of input-reading loop */
}

/*
Expand Down