diff --git a/pinos/client/connection.c b/pinos/client/connection.c index 4df1c2f69..d2445a271 100644 --- a/pinos/client/connection.c +++ b/pinos/client/connection.c @@ -291,7 +291,6 @@ pinos_connection_end_write (PinosConnection *conn, *p++ = (opcode << 24) | (size & 0xffffff); buf->buffer_size += 8 + size; - pinos_connection_flush (conn); } bool diff --git a/pinos/client/context.c b/pinos/client/context.c index 264f6ed3f..47714484e 100644 --- a/pinos/client/context.c +++ b/pinos/client/context.c @@ -38,6 +38,7 @@ typedef struct { SpaSource source; bool disconnecting; + PinosListener before_iterate; } PinosContextImpl; /** @@ -353,6 +354,14 @@ static const PinosRegistryEvents registry_events = { typedef bool (*PinosDemarshalFunc) (void *object, void *data, size_t size); +static void +on_before_iterate (PinosListener *listener, + PinosLoop *loop) +{ + PinosContextImpl *impl = SPA_CONTAINER_OF (listener, PinosContextImpl, before_iterate); + pinos_connection_flush (impl->connection); +} + static void on_context_data (SpaSource *source, int fd, @@ -446,6 +455,10 @@ pinos_context_new (PinosLoop *loop, this->state = PINOS_CONTEXT_STATE_UNCONNECTED; + pinos_signal_add (&loop->before_iterate, + &impl->before_iterate, + on_before_iterate); + pinos_map_init (&this->objects, 64); spa_list_init (&this->stream_list); @@ -482,6 +495,8 @@ pinos_context_destroy (PinosContext *context) spa_list_for_each_safe (proxy, t2, &context->proxy_list, link) pinos_proxy_destroy (proxy); + pinos_signal_remove (&impl->before_iterate); + pinos_map_clear (&context->objects); free (context->name); diff --git a/pinos/client/loop.c b/pinos/client/loop.c index 099b1d74c..583ec86e7 100644 --- a/pinos/client/loop.c +++ b/pinos/client/loop.c @@ -274,9 +274,12 @@ loop_iterate (SpaLoopControl *ctrl, int timeout) { PinosLoopImpl *impl = SPA_CONTAINER_OF (ctrl, PinosLoopImpl, control); + PinosLoop *loop = &impl->this; struct epoll_event ep[32]; int i, nfds, save_errno; + pinos_signal_emit (&loop->before_iterate, loop); + if (SPA_UNLIKELY (impl->pre_func)) impl->pre_func (ctrl, impl->hook_data); @@ -592,6 +595,7 @@ pinos_loop_new (void) spa_list_init (&impl->source_list); + pinos_signal_init (&this->before_iterate); pinos_signal_init (&this->destroy_signal); impl->loop.size = sizeof (SpaLoop); diff --git a/pinos/client/loop.h b/pinos/client/loop.h index 9517edecb..d51606260 100644 --- a/pinos/client/loop.h +++ b/pinos/client/loop.h @@ -40,6 +40,8 @@ struct _PinosLoop { SpaLoopControl *control; SpaLoopUtils *utils; + PINOS_SIGNAL (before_iterate, (PinosListener *listener, + PinosLoop *loop)); PINOS_SIGNAL (destroy_signal, (PinosListener *listener, PinosLoop *loop)); }; diff --git a/pinos/modules/module-protocol-native.c b/pinos/modules/module-protocol-native.c index 92ac5085d..09ec5ed6b 100644 --- a/pinos/modules/module-protocol-native.c +++ b/pinos/modules/module-protocol-native.c @@ -73,6 +73,8 @@ typedef struct { SpaList socket_list; SpaList client_list; + + PinosListener before_iterate; } PinosProtocolNative; typedef struct { @@ -106,6 +108,17 @@ on_resource_added (PinosListener *listener, pinos_protocol_native_server_setup (resource); } +static void +on_before_iterate (PinosListener *listener, + PinosLoop *loop) +{ + PinosProtocolNative *this = SPA_CONTAINER_OF (listener, PinosProtocolNative, before_iterate); + PinosProtocolNativeClient *client, *tmp; + + spa_list_for_each_safe (client, tmp, &this->client_list, link) + pinos_connection_flush (client->connection); +} + static void connection_data (SpaSource *source, int fd, @@ -126,27 +139,29 @@ connection_data (SpaSource *source, return; } - while (pinos_connection_get_next (conn, &opcode, &id, &message, &size)) { - PinosResource *resource; - const PinosDemarshalFunc *demarshal; + if (mask & SPA_IO_IN) { + while (pinos_connection_get_next (conn, &opcode, &id, &message, &size)) { + PinosResource *resource; + const PinosDemarshalFunc *demarshal; - pinos_log_debug ("protocol-native %p: got message %d from %u", client->impl, opcode, id); + pinos_log_debug ("protocol-native %p: got message %d from %u", client->impl, opcode, id); - resource = pinos_map_lookup (&c->objects, id); - if (resource == NULL) { - pinos_log_error ("protocol-native %p: unknown resource %u", client->impl, id); - continue; + resource = pinos_map_lookup (&c->objects, id); + if (resource == NULL) { + pinos_log_error ("protocol-native %p: unknown resource %u", client->impl, id); + continue; + } + if (opcode >= resource->iface->n_methods) { + pinos_log_error ("protocol-native %p: invalid method %u", client->impl, opcode); + continue; + } + demarshal = resource->iface->methods; + if (demarshal[opcode]) { + if (!demarshal[opcode] (resource, message, size)) + pinos_log_error ("protocol-native %p: invalid message received", client->impl); + } else + pinos_log_error ("protocol-native %p: function %d not implemented", client->impl, opcode); } - if (opcode >= resource->iface->n_methods) { - pinos_log_error ("protocol-native %p: invalid method %u", client->impl, opcode); - continue; - } - demarshal = resource->iface->methods; - if (demarshal[opcode]) { - if (!demarshal[opcode] (resource, message, size)) - pinos_log_error ("protocol-native %p: invalid message received", client->impl); - } else - pinos_log_error ("protocol-native %p: function %d not implemented", client->impl, opcode); } } @@ -409,6 +424,10 @@ pinos_protocol_native_new (PinosCore *core, if (!add_socket (impl, s)) goto error; + pinos_signal_add (&impl->core->main_loop->loop->before_iterate, + &impl->before_iterate, + on_before_iterate); + return impl; error: @@ -425,6 +444,8 @@ pinos_protocol_native_destroy (PinosProtocolNative *impl) pinos_log_debug ("protocol-native %p: destroy", impl); + pinos_signal_remove (&impl->before_iterate); + pinos_global_destroy (impl->global); spa_list_for_each_safe (object, tmp, &impl->object_list, link)