mirror of
https://github.com/ading2210/libcurl.js.git
synced 2025-05-11 13:30:01 -04:00
not yet working coroutines
This commit is contained in:
parent
2a072ecee0
commit
e5118c9c2e
8 changed files with 102 additions and 11 deletions
|
@ -104,8 +104,8 @@ To create new sessions for HTTP requests, use the `libcurl.HTTPSession` class. T
|
|||
- `options` - An optional object with various settings.
|
||||
|
||||
The valid HTTP session settings are:
|
||||
- `enable_cookies` - A boolean which indicate whether or not cookies should be persisted within the session.
|
||||
- `cookie_jar` - A blob containing the data in the cookie jar file. This should have been exported from a previous session.
|
||||
- `enable_cookies` - A boolean which indicate whether or not cookies should be persisted within the session. NOT IMPLEMENTED YET
|
||||
- `cookie_jar` - A blob containing the data in the cookie jar file. This should have been exported from a previous session. NOT IMPLEMENTED YET
|
||||
|
||||
### Creating WebSocket Connections:
|
||||
To use WebSockets, create a `libcurl.CurlWebSocket` object, which takes the following arguments:
|
||||
|
|
|
@ -27,8 +27,8 @@ EXPORTED_FUNCS="${EXPORTED_FUNCS:1}"
|
|||
|
||||
#compile options
|
||||
RUNTIME_METHODS="addFunction,removeFunction,allocate,ALLOC_NORMAL"
|
||||
COMPILER_OPTIONS="-o $MODULE_FILE -lcurl -lssl -lcrypto -lcjson -lz -lbrotlidec -lbrotlicommon -lnghttp2 -I $INCLUDE_DIR -L $LIB_DIR"
|
||||
EMSCRIPTEN_OPTIONS="-lwebsocket.js -sENVIRONMENT=worker,web -sASSERTIONS=1 -sLLD_REPORT_UNDEFINED -sALLOW_TABLE_GROWTH -sALLOW_MEMORY_GROWTH -sEXPORTED_FUNCTIONS=$EXPORTED_FUNCS -sEXPORTED_RUNTIME_METHODS=$RUNTIME_METHODS"
|
||||
COMPILER_OPTIONS="-o $MODULE_FILE -lcurl -lssl -lcrypto -lcjson -lz -lbrotlidec -lbrotlicommon -lnghttp2 -I $INCLUDE_DIR -L $LIB_DIR -Wl,--wrap=poll"
|
||||
EMSCRIPTEN_OPTIONS="-lwebsocket.js -sASYNCIFY -sENVIRONMENT=worker,web -sASSERTIONS=1 -sLLD_REPORT_UNDEFINED -sALLOW_TABLE_GROWTH -sALLOW_MEMORY_GROWTH -sEXPORTED_FUNCTIONS=$EXPORTED_FUNCS -sEXPORTED_RUNTIME_METHODS=$RUNTIME_METHODS"
|
||||
|
||||
#clean output dir
|
||||
rm -rf $OUT_DIR
|
||||
|
|
|
@ -3,7 +3,7 @@ class FTPSession extends CurlSession {
|
|||
if (!url.startsWith("ftp://") && !url.startsWith("ftps://")) {
|
||||
throw "invalid url protocol";
|
||||
}
|
||||
super();
|
||||
super(1);
|
||||
|
||||
this.url = url;
|
||||
this.options = options;
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
class CurlSession {
|
||||
constructor(options={}) {
|
||||
constructor(need_fiber=0) {
|
||||
check_loaded(true);
|
||||
|
||||
this.options = options;
|
||||
this.session_ptr = _session_create();
|
||||
this.session_ptr = _session_create(need_fiber);
|
||||
this.active_requests = 0;
|
||||
this.event_loop = null;
|
||||
this.requests_list = [];
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <stdlib.h>
|
||||
#include <poll.h>
|
||||
|
||||
#include "curl/multi.h"
|
||||
#include "curl/curl.h"
|
||||
|
@ -6,15 +7,24 @@
|
|||
#include "types.h"
|
||||
#include "request.h"
|
||||
#include "util.h"
|
||||
#include "context.h"
|
||||
|
||||
struct SessionInfo* session_create() {
|
||||
#define MINICORO_IMPL
|
||||
#include "minicoro.h"
|
||||
|
||||
struct SessionInfo* running_session;
|
||||
|
||||
struct SessionInfo* session_create(int need_fiber) {
|
||||
struct SessionInfo *session = malloc(sizeof(struct SessionInfo));
|
||||
session->multi_handle = curl_multi_init();
|
||||
session->request_active = 0;
|
||||
session->need_fiber = need_fiber;
|
||||
session->fiber_running = 0;
|
||||
session->fiber = NULL;
|
||||
return session;
|
||||
}
|
||||
|
||||
void session_perform(struct SessionInfo *session) {
|
||||
void session_thread(struct SessionInfo *session) {
|
||||
CURLMcode mc;
|
||||
session->request_active = 0;
|
||||
mc = curl_multi_perform(session->multi_handle, &session->request_active);
|
||||
|
@ -25,6 +35,68 @@ void session_perform(struct SessionInfo *session) {
|
|||
if (curl_msg && curl_msg->msg == CURLMSG_DONE) {
|
||||
finish_request(curl_msg);
|
||||
}
|
||||
|
||||
//suspend the coroutine if there are no requests active
|
||||
if (session->need_fiber && !session->request_active) {
|
||||
mco_yield(mco_running());
|
||||
}
|
||||
}
|
||||
|
||||
void session_thread_wrapper(mco_coro* fiber) {
|
||||
//infinitely loop here so we don't need to keep remaking the coroutine
|
||||
while (1) {
|
||||
session_thread(fiber->user_data);
|
||||
}
|
||||
}
|
||||
|
||||
void session_perform(struct SessionInfo *session) {
|
||||
running_session = session;
|
||||
if (!session->need_fiber) {
|
||||
session_thread(session);
|
||||
return;
|
||||
}
|
||||
|
||||
//create a new coroutine if there isn't one running already
|
||||
mco_coro* fiber;
|
||||
if (!session->fiber_running) {
|
||||
mco_desc desc = mco_desc_init(session_thread_wrapper, 0);
|
||||
desc.user_data = session;
|
||||
mco_result res = mco_create(&fiber, &desc);
|
||||
}
|
||||
else {
|
||||
fiber = session->fiber;
|
||||
}
|
||||
|
||||
if (mco_status(fiber) == MCO_SUSPENDED) {
|
||||
printf("fiber suspended \n");
|
||||
}
|
||||
if (mco_status(fiber) == MCO_DEAD) {
|
||||
printf("fiber dead \n");
|
||||
}
|
||||
if (mco_status(fiber) == MCO_NORMAL) {
|
||||
printf("fiber normal \n");
|
||||
}
|
||||
|
||||
//swich contexts into coroutine
|
||||
session->fiber_running = 1;
|
||||
mco_resume(fiber);
|
||||
}
|
||||
|
||||
|
||||
//wrap the poll function
|
||||
//we want to switch contexts when curl is polling the socket
|
||||
extern int __real_poll(struct pollfd *fds, nfds_t nfds, int timeout);
|
||||
int __wrap_poll(struct pollfd *fds, nfds_t nfds, int timeout) {
|
||||
int ret = __real_poll(fds, nfds, timeout);
|
||||
|
||||
//don't switch contexts if there is activity on the socket
|
||||
if (!running_session->need_fiber || ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
//perform the context switch if there is nothing on the socket
|
||||
mco_yield(mco_running());
|
||||
return ret;
|
||||
}
|
||||
|
||||
void session_set_options(struct SessionInfo *session, int connections_limit, int cache_limit) {
|
||||
|
@ -49,4 +121,9 @@ void session_remove_request(struct SessionInfo *session, CURL* http_handle) {
|
|||
|
||||
void session_cleanup(struct SessionInfo *session) {
|
||||
curl_multi_cleanup(session->multi_handle);
|
||||
|
||||
if (session->fiber != NULL)
|
||||
mco_destroy(session->fiber);
|
||||
|
||||
free(session);
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
#include "curl/curl.h"
|
||||
#include "minicoro.h"
|
||||
|
||||
typedef void(*DataCallback)(char* chunk_ptr, int chunk_size);
|
||||
typedef void(*EndCallback)(int error);
|
||||
|
@ -24,4 +25,7 @@ struct WSResult {
|
|||
struct SessionInfo {
|
||||
CURLM* multi_handle;
|
||||
int request_active;
|
||||
int need_fiber;
|
||||
int fiber_running;
|
||||
mco_coro* fiber;
|
||||
};
|
|
@ -11,6 +11,7 @@ CURL_PREFIX=$(realpath build/curl-wasm)
|
|||
ZLIB_PREFIX=$(realpath build/zlib-wasm)
|
||||
BROTLI_PREFIX=$(realpath build/brotli-wasm)
|
||||
NGHTTP2_PREFIX=$(realpath build/nghttp2-wasm)
|
||||
MINICORO_PREFIX=$(realpath build/minicoro-wasm)
|
||||
|
||||
if [ ! -d $OPENSSL_PREFIX ]; then
|
||||
tools/openssl.sh
|
||||
|
@ -30,9 +31,13 @@ fi
|
|||
if [ ! -d $CURL_PREFIX ]; then
|
||||
tools/curl.sh
|
||||
fi
|
||||
if [ ! -d $MINICORO_PREFIX ]; then
|
||||
tools/minicoro.sh
|
||||
fi
|
||||
|
||||
cp -r $OPENSSL_PREFIX/* $CURL_PREFIX
|
||||
cp -r $CJSON_PREFIX/* $CURL_PREFIX
|
||||
cp -r $ZLIB_PREFIX/* $CURL_PREFIX
|
||||
cp -r $BROTLI_PREFIX/* $CURL_PREFIX
|
||||
cp -r $NGHTTP2_PREFIX/* $CURL_PREFIX
|
||||
cp -r $NGHTTP2_PREFIX/* $CURL_PREFIX
|
||||
cp -r $MINICORO_PREFIX/* $CURL_PREFIX
|
6
client/tools/minicoro.sh
Executable file
6
client/tools/minicoro.sh
Executable file
|
@ -0,0 +1,6 @@
|
|||
#!/bin/bash
|
||||
|
||||
#download the minicoro library
|
||||
|
||||
mkdir -p build/minicoro-wasm/include/
|
||||
wget "https://raw.githubusercontent.com/edubart/minicoro/main/minicoro.h" -O build/minicoro-wasm/include/minicoro.h
|
Loading…
Add table
Add a link
Reference in a new issue