mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-03 09:01:54 -05:00
WIP change object model
This commit is contained in:
parent
190f01d88e
commit
c25ccbb4ba
44 changed files with 1557 additions and 2525 deletions
|
|
@ -102,12 +102,12 @@ struct _SpaProxy
|
|||
SpaNodeEventCallback event_cb;
|
||||
void *user_data;
|
||||
|
||||
SpaPollFd fds[1];
|
||||
SpaPollItem poll;
|
||||
SpaPollFd ctrl_fds[1];
|
||||
SpaPollItem ctrl_poll;
|
||||
PinosConnection *conn;
|
||||
|
||||
SpaPollFd rtfds[1];
|
||||
SpaPollItem rtpoll;
|
||||
SpaPollFd data_fds[1];
|
||||
SpaPollItem data_poll;
|
||||
|
||||
unsigned int max_inputs;
|
||||
unsigned int n_inputs;
|
||||
|
|
@ -123,17 +123,15 @@ typedef struct
|
|||
{
|
||||
PinosClientNode this;
|
||||
|
||||
PinosObject object;
|
||||
PinosInterface ifaces[1];
|
||||
|
||||
PinosCore *core;
|
||||
|
||||
SpaProxy proxy;
|
||||
|
||||
PinosListener transport_changed;
|
||||
PinosListener loop_changed;
|
||||
|
||||
int fd;
|
||||
int rtfd;
|
||||
int ctrl_fd;
|
||||
int data_fd;
|
||||
} PinosClientNodeImpl;
|
||||
|
||||
static void
|
||||
|
|
@ -862,7 +860,7 @@ spa_proxy_node_port_reuse_buffer (SpaNode *node,
|
|||
rb.buffer_id = buffer_id;
|
||||
pinos_transport_add_event (pnode->transport, &rb.event);
|
||||
cmd = PINOS_TRANSPORT_CMD_HAVE_EVENT;
|
||||
write (this->rtfds[0].fd, &cmd, 1);
|
||||
write (this->data_fds[0].fd, &cmd, 1);
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
|
@ -931,7 +929,7 @@ spa_proxy_node_process_input (SpaNode *node)
|
|||
return SPA_RESULT_ERROR;
|
||||
|
||||
cmd = PINOS_TRANSPORT_CMD_HAVE_DATA;
|
||||
write (this->rtfds[0].fd, &cmd, 1);
|
||||
write (this->data_fds[0].fd, &cmd, 1);
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
|
@ -1105,7 +1103,7 @@ proxy_on_fd_events (SpaPollNotifyData *data)
|
|||
}
|
||||
|
||||
static int
|
||||
proxy_on_rtfd_events (SpaPollNotifyData *data)
|
||||
proxy_on_data_fd_events (SpaPollNotifyData *data)
|
||||
{
|
||||
SpaProxy *this = data->user_data;
|
||||
PinosNode *pnode = this->pnode;
|
||||
|
|
@ -1113,7 +1111,7 @@ proxy_on_rtfd_events (SpaPollNotifyData *data)
|
|||
if (data->fds[0].revents & POLLIN) {
|
||||
uint8_t cmd;
|
||||
|
||||
read (this->rtfds[0].fd, &cmd, 1);
|
||||
read (this->data_fds[0].fd, &cmd, 1);
|
||||
|
||||
if (cmd & PINOS_TRANSPORT_CMD_HAVE_EVENT) {
|
||||
SpaNodeEvent event;
|
||||
|
|
@ -1194,41 +1192,39 @@ proxy_init (SpaProxy *this,
|
|||
|
||||
this->node = proxy_node;
|
||||
|
||||
this->fds[0].fd = -1;
|
||||
this->fds[0].events = POLLIN | POLLPRI | POLLERR;
|
||||
this->fds[0].revents = 0;
|
||||
this->poll.id = 0;
|
||||
this->poll.enabled = true;
|
||||
this->poll.fds = this->fds;
|
||||
this->poll.n_fds = 1;
|
||||
this->poll.idle_cb = NULL;
|
||||
this->poll.before_cb = NULL;
|
||||
this->poll.after_cb = proxy_on_fd_events;
|
||||
this->poll.user_data = this;
|
||||
this->ctrl_fds[0].fd = -1;
|
||||
this->ctrl_fds[0].events = POLLIN | POLLPRI | POLLERR;
|
||||
this->ctrl_fds[0].revents = 0;
|
||||
this->ctrl_poll.id = 0;
|
||||
this->ctrl_poll.enabled = true;
|
||||
this->ctrl_poll.fds = this->ctrl_fds;
|
||||
this->ctrl_poll.n_fds = 1;
|
||||
this->ctrl_poll.idle_cb = NULL;
|
||||
this->ctrl_poll.before_cb = NULL;
|
||||
this->ctrl_poll.after_cb = proxy_on_fd_events;
|
||||
this->ctrl_poll.user_data = this;
|
||||
|
||||
this->rtfds[0].fd = -1;
|
||||
this->rtfds[0].events = POLLIN | POLLPRI | POLLERR;
|
||||
this->rtfds[0].revents = 0;
|
||||
this->rtpoll.id = 0;
|
||||
this->rtpoll.enabled = true;
|
||||
this->rtpoll.fds = this->rtfds;
|
||||
this->rtpoll.n_fds = 1;
|
||||
this->rtpoll.idle_cb = NULL;
|
||||
this->rtpoll.before_cb = NULL;
|
||||
this->rtpoll.after_cb = proxy_on_rtfd_events;
|
||||
this->rtpoll.user_data = this;
|
||||
this->data_fds[0].fd = -1;
|
||||
this->data_fds[0].events = POLLIN | POLLPRI | POLLERR;
|
||||
this->data_fds[0].revents = 0;
|
||||
this->data_poll.id = 0;
|
||||
this->data_poll.enabled = true;
|
||||
this->data_poll.fds = this->data_fds;
|
||||
this->data_poll.n_fds = 1;
|
||||
this->data_poll.idle_cb = NULL;
|
||||
this->data_poll.before_cb = NULL;
|
||||
this->data_poll.after_cb = proxy_on_data_fd_events;
|
||||
this->data_poll.user_data = this;
|
||||
|
||||
return SPA_RESULT_RETURN_ASYNC (this->seq++);
|
||||
}
|
||||
|
||||
static void
|
||||
on_transport_changed (PinosListener *listener,
|
||||
void *object,
|
||||
void *data)
|
||||
PinosNode *node)
|
||||
{
|
||||
PinosClientNodeImpl *impl = SPA_CONTAINER_OF (listener, PinosClientNodeImpl, transport_changed);
|
||||
PinosClientNode *this = &impl->this;
|
||||
PinosNode *node = object;
|
||||
PinosTransportInfo info;
|
||||
PinosMessageTransportUpdate tu;
|
||||
PinosConnection *conn = impl->proxy.conn;
|
||||
|
|
@ -1244,6 +1240,14 @@ on_transport_changed (PinosListener *listener,
|
|||
pinos_log_error ("client-node %p: error writing connection", this);
|
||||
}
|
||||
|
||||
static void
|
||||
on_loop_changed (PinosListener *listener,
|
||||
PinosNode *node)
|
||||
{
|
||||
PinosClientNodeImpl *impl = SPA_CONTAINER_OF (listener, PinosClientNodeImpl, loop_changed);
|
||||
impl->proxy.data_loop = &node->data_loop->poll;
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
proxy_clear (SpaProxy *this)
|
||||
{
|
||||
|
|
@ -1257,35 +1261,18 @@ proxy_clear (SpaProxy *this)
|
|||
if (this->out_ports[i].valid)
|
||||
clear_port (this, &this->out_ports[i], SPA_DIRECTION_OUTPUT, i);
|
||||
}
|
||||
if (this->fds[0].fd != -1) {
|
||||
spa_poll_remove_item (this->main_loop, &this->poll);
|
||||
close (this->fds[0].fd);
|
||||
if (this->ctrl_fds[0].fd != -1) {
|
||||
spa_poll_remove_item (this->main_loop, &this->ctrl_poll);
|
||||
close (this->ctrl_fds[0].fd);
|
||||
}
|
||||
if (this->rtfds[0].fd != -1) {
|
||||
spa_poll_remove_item (this->data_loop, &this->rtpoll);
|
||||
close (this->rtfds[0].fd);
|
||||
if (this->data_fds[0].fd != -1) {
|
||||
spa_poll_remove_item (this->data_loop, &this->data_poll);
|
||||
close (this->data_fds[0].fd);
|
||||
}
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
client_node_destroy (PinosObject * object)
|
||||
{
|
||||
PinosClientNodeImpl *impl = (PinosClientNodeImpl *) object;
|
||||
PinosClientNode *this = &impl->this;
|
||||
|
||||
pinos_log_debug ("client-node %p: destroy", this);
|
||||
|
||||
proxy_clear (&impl->proxy);
|
||||
|
||||
if (impl->fd != -1)
|
||||
close (impl->fd);
|
||||
if (impl->rtfd != -1)
|
||||
close (impl->rtfd);
|
||||
free (impl);
|
||||
}
|
||||
|
||||
/**
|
||||
* pinos_client_node_new:
|
||||
* @daemon: a #PinosDaemon
|
||||
|
|
@ -1310,16 +1297,12 @@ pinos_client_node_new (PinosCore *core,
|
|||
|
||||
impl = calloc (1, sizeof (PinosClientNodeImpl));
|
||||
impl->core = core;
|
||||
impl->ctrl_fd = -1;
|
||||
impl->data_fd = -1;
|
||||
this = &impl->this;
|
||||
pinos_log_debug ("client-node %p: new", impl);
|
||||
|
||||
impl->ifaces[0].type = impl->core->registry.uri.node;
|
||||
impl->ifaces[0].iface = this;
|
||||
|
||||
pinos_object_init (&this->object,
|
||||
client_node_destroy,
|
||||
1,
|
||||
impl->ifaces);
|
||||
pinos_signal_init (&this->destroy_signal);
|
||||
|
||||
proxy_init (&impl->proxy, NULL, core->support, core->n_support);
|
||||
|
||||
|
|
@ -1331,91 +1314,93 @@ pinos_client_node_new (PinosCore *core,
|
|||
|
||||
impl->proxy.pnode = this->node;
|
||||
|
||||
impl->transport_changed.notify = on_transport_changed;
|
||||
pinos_signal_add (&this->node->transport_changed, &impl->transport_changed);
|
||||
pinos_signal_add (&this->node->transport_changed,
|
||||
&impl->transport_changed,
|
||||
on_transport_changed);
|
||||
|
||||
pinos_signal_add (&this->node->loop_changed,
|
||||
&impl->loop_changed,
|
||||
on_loop_changed);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
pinos_client_node_destroy (PinosClientNode * this)
|
||||
{
|
||||
PinosClientNodeImpl *impl = SPA_CONTAINER_OF (this, PinosClientNodeImpl, this);
|
||||
|
||||
pinos_log_debug ("client-node %p: destroy", impl);
|
||||
pinos_signal_emit (&this->destroy_signal, this);
|
||||
|
||||
pinos_node_destroy (this->node);
|
||||
|
||||
proxy_clear (&impl->proxy);
|
||||
|
||||
if (impl->ctrl_fd != -1)
|
||||
close (impl->ctrl_fd);
|
||||
if (impl->data_fd != -1)
|
||||
close (impl->data_fd);
|
||||
free (impl);
|
||||
}
|
||||
|
||||
/**
|
||||
* pinos_client_node_get_socket_pair:
|
||||
* pinos_client_node_get_ctrl_socket:
|
||||
* @node: a #PinosClientNode
|
||||
* @error: a #GError
|
||||
* @fd: a result socket
|
||||
*
|
||||
* Create or return a previously create socket pair for @node. The
|
||||
* Socket for the other end is returned.
|
||||
* socket for the other end is returned.
|
||||
*
|
||||
* Returns: a socket that can be used to send/receive buffers to node.
|
||||
* Returns: %SPA_RESULT_OK on success
|
||||
*/
|
||||
int
|
||||
pinos_client_node_get_socket_pair (PinosClientNode *this,
|
||||
GError **error)
|
||||
SpaResult
|
||||
pinos_client_node_get_ctrl_socket (PinosClientNode *this,
|
||||
int *fd)
|
||||
{
|
||||
PinosClientNodeImpl *impl = (PinosClientNodeImpl *) this;
|
||||
PinosClientNodeImpl *impl = SPA_CONTAINER_OF (this, PinosClientNodeImpl, this);
|
||||
|
||||
g_return_val_if_fail (this, -1);
|
||||
|
||||
if (impl->fd == -1) {
|
||||
if (impl->ctrl_fd == -1) {
|
||||
int fd[2];
|
||||
|
||||
if (socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, fd) != 0)
|
||||
goto no_sockets;
|
||||
return SPA_RESULT_ERRNO;
|
||||
|
||||
impl->proxy.fds[0].fd = fd[0];
|
||||
impl->proxy.conn = pinos_connection_new (impl->proxy.fds[0].fd);
|
||||
spa_poll_add_item (impl->proxy.main_loop, &impl->proxy.poll);
|
||||
impl->fd = fd[1];
|
||||
}
|
||||
return impl->fd;
|
||||
|
||||
/* ERRORS */
|
||||
no_sockets:
|
||||
{
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
g_io_error_from_errno (errno),
|
||||
"could not create socketpair: %s", strerror (errno));
|
||||
return -1;
|
||||
impl->proxy.ctrl_fds[0].fd = fd[0];
|
||||
impl->proxy.conn = pinos_connection_new (impl->proxy.ctrl_fds[0].fd);
|
||||
spa_poll_add_item (impl->proxy.main_loop, &impl->proxy.ctrl_poll);
|
||||
impl->ctrl_fd = fd[1];
|
||||
}
|
||||
*fd = impl->ctrl_fd;
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* pinos_client_node_get_rtsocket_pair:
|
||||
* pinos_client_node_get_data_socket:
|
||||
* @node: a #PinosClientNode
|
||||
* @error: a #GError
|
||||
*
|
||||
* Create or return a previously create socket pair for @node. The
|
||||
* Socket for the other end is returned.
|
||||
*
|
||||
* Returns: a #GSocket that can be used to send/receive buffers to node.
|
||||
* Returns: %SPA_RESULT_OK on success
|
||||
*/
|
||||
int
|
||||
pinos_client_node_get_rtsocket_pair (PinosClientNode *this,
|
||||
GError **error)
|
||||
SpaResult
|
||||
pinos_client_node_get_data_socket (PinosClientNode *this,
|
||||
int *fd)
|
||||
{
|
||||
PinosClientNodeImpl *impl = (PinosClientNodeImpl *) this;
|
||||
PinosClientNodeImpl *impl = SPA_CONTAINER_OF (this, PinosClientNodeImpl, this);
|
||||
|
||||
g_return_val_if_fail (this, -1);
|
||||
|
||||
if (impl->fd == -1) {
|
||||
if (impl->data_fd == -1) {
|
||||
int fd[2];
|
||||
|
||||
if (socketpair (AF_UNIX, SOCK_STREAM, 0, fd) != 0)
|
||||
goto no_sockets;
|
||||
return SPA_RESULT_ERRNO;
|
||||
|
||||
impl->proxy.rtfds[0].fd = fd[0];
|
||||
spa_poll_add_item (impl->proxy.data_loop, &impl->proxy.rtpoll);
|
||||
impl->rtfd = fd[1];
|
||||
}
|
||||
return impl->rtfd;
|
||||
|
||||
/* ERRORS */
|
||||
no_sockets:
|
||||
{
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
g_io_error_from_errno (errno),
|
||||
"could not create socketpair: %s", strerror (errno));
|
||||
return -1;
|
||||
impl->proxy.data_fds[0].fd = fd[0];
|
||||
spa_poll_add_item (impl->proxy.data_loop, &impl->proxy.data_poll);
|
||||
impl->data_fd = fd[1];
|
||||
}
|
||||
*fd = impl->data_fd;
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue