Skip to content
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

Add wake up function to packet loop #1633

Merged
merged 6 commits into from
Feb 13, 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
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ else()
endif()

project(picoquic
VERSION 1.1.18.0
VERSION 1.1.19.0
DESCRIPTION "picoquic library"
LANGUAGES C CXX)

Expand Down
7 changes: 7 additions & 0 deletions UnitTest1/unittest1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,13 @@ namespace UnitTest1
Assert::AreEqual(ret, 0);
}

TEST_METHOD(sockloop_thread)
{
int ret = sockloop_thread_test();

Assert::AreEqual(ret, 0);
}

TEST_METHOD(splay)
{
int ret = splay_test();
Expand Down
2 changes: 1 addition & 1 deletion picoquic/picoquic.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
extern "C" {
#endif

#define PICOQUIC_VERSION "1.1.18.0"
#define PICOQUIC_VERSION "1.1.19.0"
#define PICOQUIC_ERROR_CLASS 0x400
#define PICOQUIC_ERROR_DUPLICATE (PICOQUIC_ERROR_CLASS + 1)
#define PICOQUIC_ERROR_AEAD_CHECK (PICOQUIC_ERROR_CLASS + 3)
Expand Down
75 changes: 63 additions & 12 deletions picoquic/picoquic_packet_loop.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#include "picosocks.h"
#include "picoquic.h"
#include "picoquic_utils.h"

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -75,9 +76,19 @@ typedef enum {
picoquic_packet_loop_after_receive, /* Argument type size_t*: nb packets received */
picoquic_packet_loop_after_send, /* Argument type size_t*: nb packets sent */
picoquic_packet_loop_port_update, /* argument type struct_sockaddr*: new address for wakeup */
picoquic_packet_loop_time_check /* argument type . Optional. */
picoquic_packet_loop_time_check, /* argument type packet_loop_time_check_arg_t*. Optional. */
picoquic_packet_loop_wake_up /* no argument (void* NULL). Used when loop wakeup is supported */
} picoquic_packet_loop_cb_enum;

/* The time check option passes as argument a pointer to a structure specifying
* the current time and the proposed delta. The application uses the specified
* current time to compute an updated delta.
*/
typedef struct st_packet_loop_time_check_arg_t {
uint64_t current_time;
int64_t delta_t;
} packet_loop_time_check_arg_t;

typedef int (*picoquic_packet_loop_cb_fn)(picoquic_quic_t * quic, picoquic_packet_loop_cb_enum cb_mode, void * callback_ctx, void * callback_argv);

/* Packet loop option list shows support by application of optional features.
Expand All @@ -88,15 +99,6 @@ typedef struct st_picoquic_packet_loop_options_t {
int do_time_check : 1; /* App should be polled for next time before sock select */
} picoquic_packet_loop_options_t;

/* The time check option passes as argument a pointer to a structure specifying
* the current time and the proposed delta. The application uses the specified
* current time to compute an updated delta.
*/
typedef struct st_packet_loop_time_check_arg_t {
uint64_t current_time;
int64_t delta_t;
} packet_loop_time_check_arg_t;

/* Version 2 of packet loop, works in progress.
* Parameters are set in a struct, for future
* extensibility.
Expand All @@ -117,8 +119,57 @@ int picoquic_packet_loop_v2(picoquic_quic_t* quic,
picoquic_packet_loop_cb_fn loop_callback,
void * loop_callback_ctx);

/* Two versions of the packet loop, one portable and one speciailezed
* for winsock.
/* Threaded version of packet loop, when running picoquic in a background thread.
*
* Thread is started by calling picoquic_start_network_thread, which
* returns an argument of type picoquic_network_thread_ctx_t. Returns a NULL
* pointer if the thread could not be created.
*
* If the application needs to post new data or otherwise interact with
* the quic connections, it should call picoquic_wake_up_network_thread,
* passing the thread context as an argument. This with trigger a
* callback of type `picoquic_packet_loop_wake_up`, which executes
* in the context of the network thread. Picoquic APIs can be called
* in this context without worrying about concurrency issues.
*
* If the application wants to close the network thread, it calls
* picoquic_close_network_thread, passing the thread context as an argument.
* The network thread context will be freed during that call.
*/

typedef struct st_picoquic_network_thread_ctx_t {
picoquic_quic_t* quic;
picoquic_packet_loop_param_t* param;
picoquic_packet_loop_cb_fn loop_callback;
void* loop_callback_ctx;
picoquic_thread_t thread_id;
#ifdef _WINDOWS
HANDLE wake_up_event;
#else
int wake_up_pipe_fd[2];
#endif
int is_threaded;
int wake_up_defined;
volatile int thread_is_ready;
volatile int thread_should_close;
volatile int thread_is_closed;
int return_code;
} picoquic_network_thread_ctx_t;

picoquic_network_thread_ctx_t* picoquic_start_network_thread(
picoquic_quic_t* quic,
picoquic_packet_loop_param_t* param,
picoquic_packet_loop_cb_fn loop_callback,
void* loop_callback_ctx,
int * ret);

int picoquic_wake_up_network_thread(picoquic_network_thread_ctx_t* thread_ctx);
void picoquic_delete_network_thread(picoquic_network_thread_ctx_t* thread_ctx);


/* Legacy versions the packet loop, one portable and one specialized
* for winsock. Keeping these API for compatibility, but the implementation
* redirects to picoquic_packet_loop_v2.
*/
int picoquic_packet_loop(picoquic_quic_t* quic,
int local_port,
Expand Down
2 changes: 0 additions & 2 deletions picoquic/picosocks.c
Original file line number Diff line number Diff line change
Expand Up @@ -912,8 +912,6 @@ int picoquic_recvmsg_async_start(picoquic_recvmsg_async_ctx_t* ctx)
}
}
else {
DBG_PRINTF("Receive async immediate (WSARecvMsg) on UDP socket %d -- %d bytes !\n",
(int)ctx->fd, numberOfBytesReceived);
ctx->nb_immediate_receive++;
}
} while (should_retry);
Expand Down
Loading
Loading