mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
module-protocol-native: Handle pending connect
Do not return an error immediately if connect() fails with EAGAIN. Check if it completed successfully with getsockopt() when the socket becomes writable instead. This is the way to handle non-blocking connect() by the book but after testing it seems that the case when connect() fails with EAGAIN is when the listen backlog is full on the server side and in that case the server socket is closed. So even though connect() completes successfully according to getsockopt() the client socket is no longer usable (on_remote_data() will get both SPA_IO_OUT and SPA_IO_HUP in mask on the first call after connect() returned EAGAIN).
This commit is contained in:
parent
330e694e63
commit
1e6b7b8a83
2 changed files with 24 additions and 2 deletions
|
|
@ -29,6 +29,7 @@
|
|||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
|
@ -106,6 +107,7 @@ struct client {
|
|||
|
||||
int ref;
|
||||
|
||||
unsigned int connected:1;
|
||||
unsigned int disconnecting:1;
|
||||
unsigned int need_flush:1;
|
||||
unsigned int paused:1;
|
||||
|
|
@ -826,6 +828,21 @@ on_remote_data(void *data, int fd, uint32_t mask)
|
|||
goto error;
|
||||
}
|
||||
if (mask & SPA_IO_OUT || impl->need_flush) {
|
||||
if (!impl->connected) {
|
||||
socklen_t len = sizeof res;
|
||||
|
||||
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &res, &len) < 0) {
|
||||
res = -errno;
|
||||
pw_log_error(NAME" getsockopt: %m");
|
||||
goto error;
|
||||
}
|
||||
if (res != 0) {
|
||||
res = -res;
|
||||
goto error;
|
||||
}
|
||||
impl->connected = true;
|
||||
pw_log_debug(NAME" %p: connected, fd %d", impl, fd);
|
||||
}
|
||||
impl->need_flush = false;
|
||||
res = pw_protocol_native_connection_flush(conn);
|
||||
if (res >= 0) {
|
||||
|
|
@ -881,6 +898,7 @@ static int impl_connect_fd(struct pw_protocol_client *client, int fd, bool do_cl
|
|||
struct client *impl = SPA_CONTAINER_OF(client, struct client, this);
|
||||
int res;
|
||||
|
||||
impl->connected = false;
|
||||
impl->disconnecting = false;
|
||||
|
||||
pw_protocol_native_connection_set_fd(impl->connection, fd);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue