Compare commits
14 Commits
server_thr
...
server_thr
Author | SHA1 | Date | |
---|---|---|---|
1ad679714b | |||
612d9722a2 | |||
1f8200e295 | |||
4ae7d1e9a9 | |||
49357566cb | |||
c5d962b6fd | |||
54272a931a | |||
59d1b0a269 | |||
58ea238fb2 | |||
13c4aa1a3b | |||
caf594c90e | |||
688477ff65 | |||
ac539e1312 | |||
a57c7d3a2b |
@ -43,6 +43,11 @@
|
|||||||
# define SCRCPY_SDL_HAS_WINDOW_ALWAYS_ON_TOP
|
# define SCRCPY_SDL_HAS_WINDOW_ALWAYS_ON_TOP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if SDL_VERSION_ATLEAST(2, 0, 6)
|
||||||
|
// <https://github.com/libsdl-org/SDL/commit/d7a318de563125e5bb465b1000d6bc9576fbc6fc>
|
||||||
|
# define SCRCPY_SDL_HAS_HINT_TOUCH_MOUSE_EVENTS
|
||||||
|
#endif
|
||||||
|
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 8)
|
#if SDL_VERSION_ATLEAST(2, 0, 8)
|
||||||
// <https://hg.libsdl.org/SDL/rev/dfde5d3f9781>
|
// <https://hg.libsdl.org/SDL/rev/dfde5d3f9781>
|
||||||
# define SCRCPY_SDL_HAS_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR
|
# define SCRCPY_SDL_HAS_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR
|
||||||
|
@ -2,4 +2,3 @@
|
|||||||
#define EVENT_STREAM_STOPPED (SDL_USEREVENT + 1)
|
#define EVENT_STREAM_STOPPED (SDL_USEREVENT + 1)
|
||||||
#define EVENT_SERVER_CONNECTION_FAILED (SDL_USEREVENT + 2)
|
#define EVENT_SERVER_CONNECTION_FAILED (SDL_USEREVENT + 2)
|
||||||
#define EVENT_SERVER_CONNECTED (SDL_USEREVENT + 3)
|
#define EVENT_SERVER_CONNECTED (SDL_USEREVENT + 3)
|
||||||
#define EVENT_SERVER_DISCONNECTED (SDL_USEREVENT + 4)
|
|
||||||
|
@ -79,29 +79,8 @@ BOOL WINAPI windows_ctrl_handler(DWORD ctrl_type) {
|
|||||||
}
|
}
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
// init SDL and set appropriate hints
|
static void
|
||||||
static bool
|
sdl_set_hints(const char *render_driver) {
|
||||||
sdl_init_and_configure(bool display, const char *render_driver,
|
|
||||||
bool disable_screensaver) {
|
|
||||||
uint32_t flags = display ? SDL_INIT_VIDEO : SDL_INIT_EVENTS;
|
|
||||||
if (SDL_Init(flags)) {
|
|
||||||
LOGC("Could not initialize SDL: %s", SDL_GetError());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
atexit(SDL_Quit);
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
// Clean up properly on Ctrl+C on Windows
|
|
||||||
bool ok = SetConsoleCtrlHandler(windows_ctrl_handler, TRUE);
|
|
||||||
if (!ok) {
|
|
||||||
LOGW("Could not set Ctrl+C handler");
|
|
||||||
}
|
|
||||||
#endif // _WIN32
|
|
||||||
|
|
||||||
if (!display) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (render_driver && !SDL_SetHint(SDL_HINT_RENDER_DRIVER, render_driver)) {
|
if (render_driver && !SDL_SetHint(SDL_HINT_RENDER_DRIVER, render_driver)) {
|
||||||
LOGW("Could not set render driver");
|
LOGW("Could not set render driver");
|
||||||
@ -119,6 +98,15 @@ sdl_init_and_configure(bool display, const char *render_driver,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef SCRCPY_SDL_HAS_HINT_TOUCH_MOUSE_EVENTS
|
||||||
|
// Disable synthetic mouse events from touch events
|
||||||
|
// Touch events with id SDL_TOUCH_MOUSEID are ignored anyway, but it is
|
||||||
|
// better not to generate them in the first place.
|
||||||
|
if (!SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0")) {
|
||||||
|
LOGW("Could not disable synthetic mouse events");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef SCRCPY_SDL_HAS_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR
|
#ifdef SCRCPY_SDL_HAS_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR
|
||||||
// Disable compositor bypassing on X11
|
// Disable compositor bypassing on X11
|
||||||
if (!SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0")) {
|
if (!SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0")) {
|
||||||
@ -130,6 +118,21 @@ sdl_init_and_configure(bool display, const char *render_driver,
|
|||||||
if (!SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0")) {
|
if (!SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0")) {
|
||||||
LOGW("Could not disable minimize on focus loss");
|
LOGW("Could not disable minimize on focus loss");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sdl_configure(bool display, bool disable_screensaver) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
// Clean up properly on Ctrl+C on Windows
|
||||||
|
bool ok = SetConsoleCtrlHandler(windows_ctrl_handler, TRUE);
|
||||||
|
if (!ok) {
|
||||||
|
LOGW("Could not set Ctrl+C handler");
|
||||||
|
}
|
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
|
if (!display) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (disable_screensaver) {
|
if (disable_screensaver) {
|
||||||
LOGD("Screensaver disabled");
|
LOGD("Screensaver disabled");
|
||||||
@ -138,8 +141,6 @@ sdl_init_and_configure(bool display, const char *render_driver,
|
|||||||
LOGD("Screensaver enabled");
|
LOGD("Screensaver enabled");
|
||||||
SDL_EnableScreenSaver();
|
SDL_EnableScreenSaver();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
@ -158,10 +159,6 @@ static enum event_result
|
|||||||
handle_event(struct scrcpy *s, const struct scrcpy_options *options,
|
handle_event(struct scrcpy *s, const struct scrcpy_options *options,
|
||||||
SDL_Event *event) {
|
SDL_Event *event) {
|
||||||
switch (event->type) {
|
switch (event->type) {
|
||||||
case EVENT_SERVER_DISCONNECTED:
|
|
||||||
LOGD("Server disconnected");
|
|
||||||
// Do nothing, will be managed by the "stream stopped" event
|
|
||||||
break;
|
|
||||||
case EVENT_STREAM_STOPPED:
|
case EVENT_STREAM_STOPPED:
|
||||||
LOGD("Video stream stopped");
|
LOGD("Video stream stopped");
|
||||||
return EVENT_RESULT_STOPPED_BY_EOS;
|
return EVENT_RESULT_STOPPED_BY_EOS;
|
||||||
@ -224,9 +221,6 @@ static bool
|
|||||||
await_for_server(void) {
|
await_for_server(void) {
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
while (SDL_WaitEvent(&event)) {
|
while (SDL_WaitEvent(&event)) {
|
||||||
// Should never receive disconnected event before connected
|
|
||||||
assert(event.type != EVENT_SERVER_DISCONNECTED);
|
|
||||||
|
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case SDL_QUIT:
|
case SDL_QUIT:
|
||||||
LOGD("User requested to quit");
|
LOGD("User requested to quit");
|
||||||
@ -312,7 +306,8 @@ server_on_disconnected(struct server *server, void *userdata) {
|
|||||||
(void) server;
|
(void) server;
|
||||||
(void) userdata;
|
(void) userdata;
|
||||||
|
|
||||||
PUSH_EVENT(EVENT_SERVER_DISCONNECTED);
|
LOGD("Server disconnected");
|
||||||
|
// Do nothing, will be managed by the "stream stopped" event
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -320,6 +315,14 @@ scrcpy(struct scrcpy_options *options) {
|
|||||||
static struct scrcpy scrcpy;
|
static struct scrcpy scrcpy;
|
||||||
struct scrcpy *s = &scrcpy;
|
struct scrcpy *s = &scrcpy;
|
||||||
|
|
||||||
|
// Minimal SDL initialization
|
||||||
|
if (SDL_Init(SDL_INIT_EVENTS)) {
|
||||||
|
LOGC("Could not initialize SDL: %s", SDL_GetError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
atexit(SDL_Quit);
|
||||||
|
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
bool server_started = false;
|
bool server_started = false;
|
||||||
@ -336,7 +339,6 @@ scrcpy(struct scrcpy_options *options) {
|
|||||||
bool controller_started = false;
|
bool controller_started = false;
|
||||||
bool screen_initialized = false;
|
bool screen_initialized = false;
|
||||||
|
|
||||||
bool record = !!options->record_filename;
|
|
||||||
struct server_params params = {
|
struct server_params params = {
|
||||||
.serial = options->serial,
|
.serial = options->serial,
|
||||||
.log_level = options->log_level,
|
.log_level = options->log_level,
|
||||||
@ -365,18 +367,24 @@ scrcpy(struct scrcpy_options *options) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO SDL_Init(SDL_INIT_EVENTS) before starting server
|
|
||||||
if (!server_start(&s->server)) {
|
if (!server_start(&s->server)) {
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
server_started = true;
|
server_started = true;
|
||||||
|
|
||||||
if (!sdl_init_and_configure(options->display, options->render_driver,
|
if (options->display) {
|
||||||
options->disable_screensaver)) {
|
sdl_set_hints(options->render_driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize SDL video in addition if display is enabled
|
||||||
|
if (options->display && SDL_Init(SDL_INIT_VIDEO)) {
|
||||||
|
LOGC("Could not initialize SDL: %s", SDL_GetError());
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sdl_configure(options->display, options->disable_screensaver);
|
||||||
|
|
||||||
// Await for server without blocking Ctrl+C handling
|
// Await for server without blocking Ctrl+C handling
|
||||||
if (!await_for_server()) {
|
if (!await_for_server()) {
|
||||||
goto end;
|
goto end;
|
||||||
@ -403,7 +411,7 @@ scrcpy(struct scrcpy_options *options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct recorder *rec = NULL;
|
struct recorder *rec = NULL;
|
||||||
if (record) {
|
if (options->record_filename) {
|
||||||
if (!recorder_init(&s->recorder,
|
if (!recorder_init(&s->recorder,
|
||||||
options->record_filename,
|
options->record_filename,
|
||||||
options->record_format,
|
options->record_format,
|
||||||
|
@ -148,10 +148,10 @@ disable_tunnel(struct server *server) {
|
|||||||
return disable_tunnel_reverse(serial);
|
return disable_tunnel_reverse(serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
static sc_socket
|
static bool
|
||||||
listen_on_port(uint16_t port) {
|
listen_on_port(sc_socket socket, uint16_t port) {
|
||||||
#define IPV4_LOCALHOST 0x7F000001
|
#define IPV4_LOCALHOST 0x7F000001
|
||||||
return net_listen(IPV4_LOCALHOST, port, 1);
|
return net_listen(socket, IPV4_LOCALHOST, port, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
@ -171,11 +171,17 @@ enable_tunnel_reverse_any_port(struct server *server,
|
|||||||
// client can listen before starting the server app, so there is no
|
// client can listen before starting the server app, so there is no
|
||||||
// need to try to connect until the server socket is listening on the
|
// need to try to connect until the server socket is listening on the
|
||||||
// device.
|
// device.
|
||||||
server->server_socket = listen_on_port(port);
|
sc_socket server_socket = net_socket();
|
||||||
if (server->server_socket != SC_INVALID_SOCKET) {
|
if (server_socket != SC_INVALID_SOCKET) {
|
||||||
// success
|
bool ok = listen_on_port(server_socket, port);
|
||||||
server->local_port = port;
|
if (ok) {
|
||||||
return true;
|
// success
|
||||||
|
server->server_socket = server_socket;
|
||||||
|
server->local_port = port;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
net_close(server_socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
// failure, disable tunnel and try another port
|
// failure, disable tunnel and try another port
|
||||||
@ -335,11 +341,17 @@ execute_server(struct server *server, const struct server_params *params) {
|
|||||||
|
|
||||||
static sc_socket
|
static sc_socket
|
||||||
connect_and_read_byte(uint16_t port) {
|
connect_and_read_byte(uint16_t port) {
|
||||||
sc_socket socket = net_connect(IPV4_LOCALHOST, port);
|
sc_socket socket = net_socket();
|
||||||
if (socket == SC_INVALID_SOCKET) {
|
if (socket == SC_INVALID_SOCKET) {
|
||||||
return SC_INVALID_SOCKET;
|
return SC_INVALID_SOCKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ok = net_connect(socket, IPV4_LOCALHOST, port);
|
||||||
|
if (!ok) {
|
||||||
|
net_close(socket);
|
||||||
|
return SC_INVALID_SOCKET;
|
||||||
|
}
|
||||||
|
|
||||||
char byte;
|
char byte;
|
||||||
// the connection may succeed even if the server behind the "adb tunnel"
|
// the connection may succeed even if the server behind the "adb tunnel"
|
||||||
// is not listening, so read one byte to detect a working connection
|
// is not listening, so read one byte to detect a working connection
|
||||||
@ -352,7 +364,8 @@ connect_and_read_byte(uint16_t port) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static sc_socket
|
static sc_socket
|
||||||
connect_to_server(uint16_t port, uint32_t attempts, uint32_t delay) {
|
connect_to_server(struct server *server, uint32_t attempts, sc_tick delay) {
|
||||||
|
uint16_t port = server->local_port;
|
||||||
do {
|
do {
|
||||||
LOGD("Remaining connection attempts: %d", (int) attempts);
|
LOGD("Remaining connection attempts: %d", (int) attempts);
|
||||||
sc_socket socket = connect_and_read_byte(port);
|
sc_socket socket = connect_and_read_byte(port);
|
||||||
@ -360,9 +373,17 @@ connect_to_server(uint16_t port, uint32_t attempts, uint32_t delay) {
|
|||||||
// it worked!
|
// it worked!
|
||||||
return socket;
|
return socket;
|
||||||
}
|
}
|
||||||
// TODO use mutex + condvar + bool stopped
|
|
||||||
if (attempts) {
|
if (attempts) {
|
||||||
SDL_Delay(delay);
|
sc_mutex_lock(&server->mutex);
|
||||||
|
// Ignore timedwait return (spurious wake ups are harmless)
|
||||||
|
sc_cond_timedwait(&server->stopped_cond, &server->mutex,
|
||||||
|
sc_tick_now() + delay);
|
||||||
|
bool stopped = server->stopped;
|
||||||
|
sc_mutex_unlock(&server->mutex);
|
||||||
|
if (stopped) {
|
||||||
|
LOGI("Connection attempt stopped");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} while (--attempts > 0);
|
} while (--attempts > 0);
|
||||||
return SC_INVALID_SOCKET;
|
return SC_INVALID_SOCKET;
|
||||||
@ -392,7 +413,16 @@ server_init(struct server *server, const struct server_params *params,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ok = sc_cond_init(&server->stopped_cond);
|
||||||
|
if (!ok) {
|
||||||
|
sc_cond_destroy(&server->process_terminated_cond);
|
||||||
|
sc_mutex_destroy(&server->mutex);
|
||||||
|
server_params_destroy(&server->params);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
server->process_terminated = false;
|
server->process_terminated = false;
|
||||||
|
server->stopped = false;
|
||||||
server->connected = false;
|
server->connected = false;
|
||||||
|
|
||||||
server->server_socket = SC_INVALID_SOCKET;
|
server->server_socket = SC_INVALID_SOCKET;
|
||||||
@ -539,19 +569,23 @@ server_connect_to(struct server *server, struct server_info *info) {
|
|||||||
server->server_socket = SC_INVALID_SOCKET;
|
server->server_socket = SC_INVALID_SOCKET;
|
||||||
} else {
|
} else {
|
||||||
uint32_t attempts = 100;
|
uint32_t attempts = 100;
|
||||||
uint32_t delay = 100; // ms
|
sc_tick delay = SC_TICK_FROM_MS(100);
|
||||||
server->video_socket =
|
server->video_socket = connect_to_server(server, attempts, delay);
|
||||||
connect_to_server(server->local_port, attempts, delay);
|
|
||||||
if (server->video_socket == SC_INVALID_SOCKET) {
|
if (server->video_socket == SC_INVALID_SOCKET) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we know that the device is listening, we don't need several attempts
|
// we know that the device is listening, we don't need several attempts
|
||||||
server->control_socket =
|
server->control_socket = net_socket();
|
||||||
net_connect(IPV4_LOCALHOST, server->local_port);
|
|
||||||
if (server->control_socket == SC_INVALID_SOCKET) {
|
if (server->control_socket == SC_INVALID_SOCKET) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
bool ok = net_connect(server->control_socket, IPV4_LOCALHOST,
|
||||||
|
server->local_port);
|
||||||
|
if (!ok) {
|
||||||
|
net_close(server->control_socket);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// we don't need the adb tunnel anymore
|
// we don't need the adb tunnel anymore
|
||||||
@ -564,6 +598,11 @@ server_connect_to(struct server *server, struct server_info *info) {
|
|||||||
|
|
||||||
void
|
void
|
||||||
server_stop(struct server *server) {
|
server_stop(struct server *server) {
|
||||||
|
sc_mutex_lock(&server->mutex);
|
||||||
|
server->stopped = true;
|
||||||
|
sc_cond_signal(&server->stopped_cond);
|
||||||
|
sc_mutex_unlock(&server->mutex);
|
||||||
|
|
||||||
if (server->server_socket != SC_INVALID_SOCKET) {
|
if (server->server_socket != SC_INVALID_SOCKET) {
|
||||||
if (!net_interrupt(server->server_socket)) {
|
if (!net_interrupt(server->server_socket)) {
|
||||||
LOGW("Could not interrupt server socket");
|
LOGW("Could not interrupt server socket");
|
||||||
@ -631,6 +670,7 @@ server_destroy(struct server *server) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
server_params_destroy(&server->params);
|
server_params_destroy(&server->params);
|
||||||
|
sc_cond_destroy(&server->stopped_cond);
|
||||||
sc_cond_destroy(&server->process_terminated_cond);
|
sc_cond_destroy(&server->process_terminated_cond);
|
||||||
sc_mutex_destroy(&server->mutex);
|
sc_mutex_destroy(&server->mutex);
|
||||||
}
|
}
|
||||||
|
@ -47,9 +47,13 @@ struct server {
|
|||||||
sc_thread thread;
|
sc_thread thread;
|
||||||
|
|
||||||
sc_mutex mutex;
|
sc_mutex mutex;
|
||||||
|
|
||||||
sc_cond process_terminated_cond;
|
sc_cond process_terminated_cond;
|
||||||
bool process_terminated;
|
bool process_terminated;
|
||||||
|
|
||||||
|
sc_cond stopped_cond;
|
||||||
|
bool stopped;
|
||||||
|
|
||||||
bool connected; // written by connect_thread
|
bool connected; // written by connect_thread
|
||||||
struct server_info info; // initialized once connected
|
struct server_info info; // initialized once connected
|
||||||
|
|
||||||
|
@ -94,13 +94,18 @@ net_perror(const char *s) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sc_socket
|
sc_socket
|
||||||
net_connect(uint32_t addr, uint16_t port) {
|
net_socket(void) {
|
||||||
sc_raw_socket raw_sock = socket(AF_INET, SOCK_STREAM, 0);
|
sc_raw_socket raw_sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
sc_socket sock = wrap(raw_sock);
|
sc_socket sock = wrap(raw_sock);
|
||||||
if (sock == SC_INVALID_SOCKET) {
|
if (sock == SC_INVALID_SOCKET) {
|
||||||
net_perror("socket");
|
net_perror("socket");
|
||||||
return SC_INVALID_SOCKET;
|
|
||||||
}
|
}
|
||||||
|
return sock;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
net_connect(sc_socket socket, uint32_t addr, uint16_t port) {
|
||||||
|
sc_raw_socket raw_sock = unwrap(socket);
|
||||||
|
|
||||||
SOCKADDR_IN sin;
|
SOCKADDR_IN sin;
|
||||||
sin.sin_family = AF_INET;
|
sin.sin_family = AF_INET;
|
||||||
@ -109,21 +114,15 @@ net_connect(uint32_t addr, uint16_t port) {
|
|||||||
|
|
||||||
if (connect(raw_sock, (SOCKADDR *) &sin, sizeof(sin)) == SOCKET_ERROR) {
|
if (connect(raw_sock, (SOCKADDR *) &sin, sizeof(sin)) == SOCKET_ERROR) {
|
||||||
net_perror("connect");
|
net_perror("connect");
|
||||||
net_close(sock);
|
return false;
|
||||||
return SC_INVALID_SOCKET;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return sock;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
sc_socket
|
bool
|
||||||
net_listen(uint32_t addr, uint16_t port, int backlog) {
|
net_listen(sc_socket socket, uint32_t addr, uint16_t port, int backlog) {
|
||||||
sc_raw_socket raw_sock = socket(AF_INET, SOCK_STREAM, 0);
|
sc_raw_socket raw_sock = unwrap(socket);
|
||||||
sc_socket sock = wrap(raw_sock);
|
|
||||||
if (sock == SC_INVALID_SOCKET) {
|
|
||||||
net_perror("socket");
|
|
||||||
return SC_INVALID_SOCKET;
|
|
||||||
}
|
|
||||||
|
|
||||||
int reuse = 1;
|
int reuse = 1;
|
||||||
if (setsockopt(raw_sock, SOL_SOCKET, SO_REUSEADDR, (const void *) &reuse,
|
if (setsockopt(raw_sock, SOL_SOCKET, SO_REUSEADDR, (const void *) &reuse,
|
||||||
@ -138,17 +137,15 @@ net_listen(uint32_t addr, uint16_t port, int backlog) {
|
|||||||
|
|
||||||
if (bind(raw_sock, (SOCKADDR *) &sin, sizeof(sin)) == SOCKET_ERROR) {
|
if (bind(raw_sock, (SOCKADDR *) &sin, sizeof(sin)) == SOCKET_ERROR) {
|
||||||
net_perror("bind");
|
net_perror("bind");
|
||||||
net_close(sock);
|
return false;
|
||||||
return SC_INVALID_SOCKET;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listen(raw_sock, backlog) == SOCKET_ERROR) {
|
if (listen(raw_sock, backlog) == SOCKET_ERROR) {
|
||||||
net_perror("listen");
|
net_perror("listen");
|
||||||
net_close(sock);
|
return false;
|
||||||
return SC_INVALID_SOCKET;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return sock;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
sc_socket
|
sc_socket
|
||||||
|
@ -31,10 +31,13 @@ void
|
|||||||
net_cleanup(void);
|
net_cleanup(void);
|
||||||
|
|
||||||
sc_socket
|
sc_socket
|
||||||
net_connect(uint32_t addr, uint16_t port);
|
net_socket(void);
|
||||||
|
|
||||||
sc_socket
|
bool
|
||||||
net_listen(uint32_t addr, uint16_t port, int backlog);
|
net_connect(sc_socket socket, uint32_t addr, uint16_t port);
|
||||||
|
|
||||||
|
bool
|
||||||
|
net_listen(sc_socket socket, uint32_t addr, uint16_t port, int backlog);
|
||||||
|
|
||||||
sc_socket
|
sc_socket
|
||||||
net_accept(sc_socket server_socket);
|
net_accept(sc_socket server_socket);
|
||||||
|
Reference in New Issue
Block a user