mirror of
https://github.com/ading2210/libcurl.js.git
synced 2025-05-14 06:50:00 -04:00
not yet working coroutines
This commit is contained in:
parent
2a072ecee0
commit
e5118c9c2e
8 changed files with 102 additions and 11 deletions
|
@ -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);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue