mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-04 13:30:12 -05:00
Add proxy destroy
Make the current destroy method on the core for proxies to remove the server side resource. Make a new destroy method on the registry to destroy globals. Remove the destroy method on the client-node media-session: monitor the dsp and device node states to manage the session state
This commit is contained in:
parent
ce4cfd78e7
commit
59f10ad453
10 changed files with 276 additions and 157 deletions
|
|
@ -42,6 +42,8 @@
|
||||||
#define DEFAULT_CHANNELS 2
|
#define DEFAULT_CHANNELS 2
|
||||||
#define DEFAULT_SAMPLERATE 48000
|
#define DEFAULT_SAMPLERATE 48000
|
||||||
|
|
||||||
|
#define DEFAULT_IDLE_SECONDS 3
|
||||||
|
|
||||||
#define MIN_QUANTUM_SIZE 64
|
#define MIN_QUANTUM_SIZE 64
|
||||||
#define MAX_QUANTUM_SIZE 1024
|
#define MAX_QUANTUM_SIZE 1024
|
||||||
|
|
||||||
|
|
@ -86,6 +88,7 @@ struct node {
|
||||||
struct spa_list session_link;
|
struct spa_list session_link;
|
||||||
struct session *session;
|
struct session *session;
|
||||||
|
|
||||||
|
struct session *manager;
|
||||||
struct spa_list port_list;
|
struct spa_list port_list;
|
||||||
|
|
||||||
enum pw_direction direction;
|
enum pw_direction direction;
|
||||||
|
|
@ -126,7 +129,8 @@ struct session {
|
||||||
|
|
||||||
struct node *node;
|
struct node *node;
|
||||||
struct node *dsp;
|
struct node *dsp;
|
||||||
struct link *link;
|
struct pw_link_proxy *link;
|
||||||
|
struct spa_hook link_listener;
|
||||||
|
|
||||||
struct spa_list node_list;
|
struct spa_list node_list;
|
||||||
|
|
||||||
|
|
@ -173,18 +177,152 @@ static void schedule_rescan(struct impl *impl)
|
||||||
static void remove_idle_timeout(struct session *sess)
|
static void remove_idle_timeout(struct session *sess)
|
||||||
{
|
{
|
||||||
struct impl *impl = sess->impl;
|
struct impl *impl = sess->impl;
|
||||||
|
struct pw_loop *main_loop = pw_core_get_main_loop(impl->core);
|
||||||
|
|
||||||
if (sess->idle_timeout) {
|
if (sess->idle_timeout) {
|
||||||
pw_loop_destroy_source(pw_core_get_main_loop(impl->core), sess->idle_timeout);
|
pw_loop_destroy_source(main_loop, sess->idle_timeout);
|
||||||
sess->idle_timeout = NULL;
|
sess->idle_timeout = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void idle_timeout(void *data, uint64_t expirations)
|
||||||
|
{
|
||||||
|
struct session *sess = data;
|
||||||
|
struct impl *impl = sess->impl;
|
||||||
|
struct spa_command *cmd = &SPA_NODE_COMMAND_INIT(SPA_NODE_COMMAND_Suspend);
|
||||||
|
|
||||||
|
pw_log_debug(NAME " %p: session %d idle timeout", impl, sess->id);
|
||||||
|
|
||||||
|
remove_idle_timeout(sess);
|
||||||
|
|
||||||
|
pw_node_proxy_send_command((struct pw_node_proxy*)sess->node->obj.proxy, cmd);
|
||||||
|
if (sess->dsp)
|
||||||
|
pw_node_proxy_send_command((struct pw_node_proxy*)sess->dsp->obj.proxy, cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_idle_timeout(struct session *sess)
|
||||||
|
{
|
||||||
|
struct timespec value;
|
||||||
|
struct impl *impl = sess->impl;
|
||||||
|
struct pw_loop *main_loop = pw_core_get_main_loop(impl->core);
|
||||||
|
|
||||||
|
if (sess->idle_timeout == NULL)
|
||||||
|
sess->idle_timeout = pw_loop_add_timer(main_loop, idle_timeout, sess);
|
||||||
|
|
||||||
|
value.tv_sec = DEFAULT_IDLE_SECONDS;
|
||||||
|
value.tv_nsec = 0;
|
||||||
|
pw_loop_update_timer(main_loop, sess->idle_timeout, &value, NULL, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int unlink_session_dsp(struct impl *impl, struct session *session)
|
||||||
|
{
|
||||||
|
pw_core_proxy_destroy(impl->core_proxy, (struct pw_proxy*)session->link);
|
||||||
|
session->link = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int on_node_idle(struct impl *impl, struct node *node)
|
||||||
|
{
|
||||||
|
struct session *sess = node->manager;
|
||||||
|
|
||||||
|
if (sess == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (node->type) {
|
||||||
|
case NODE_TYPE_DSP:
|
||||||
|
pw_log_debug(NAME" %p: dsp idle for session %d", impl, sess->id);
|
||||||
|
if (sess->link)
|
||||||
|
unlink_session_dsp(impl, sess);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NODE_TYPE_DEVICE:
|
||||||
|
pw_log_debug(NAME" %p: device idle for session %d", impl, sess->id);
|
||||||
|
sess->busy = false;
|
||||||
|
sess->exclusive = false;
|
||||||
|
add_idle_timeout(sess);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int link_session_dsp(struct impl *impl, struct session *session)
|
||||||
|
{
|
||||||
|
struct pw_properties *props;
|
||||||
|
|
||||||
|
pw_log_debug(NAME " %p: link session dsp '%d'", impl, session->id);
|
||||||
|
|
||||||
|
props = pw_properties_new(NULL, NULL);
|
||||||
|
// pw_properties_set(props, PW_LINK_PROP_PASSIVE, "true");
|
||||||
|
if (session->direction == PW_DIRECTION_OUTPUT) {
|
||||||
|
pw_properties_setf(props, PW_LINK_OUTPUT_NODE_ID, "%d", session->dsp->info->id);
|
||||||
|
pw_properties_setf(props, PW_LINK_OUTPUT_PORT_ID, "%d", -1);
|
||||||
|
pw_properties_setf(props, PW_LINK_INPUT_NODE_ID, "%d", session->node->info->id);
|
||||||
|
pw_properties_setf(props, PW_LINK_INPUT_PORT_ID, "%d", -1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pw_properties_setf(props, PW_LINK_OUTPUT_NODE_ID, "%d", session->node->info->id);
|
||||||
|
pw_properties_setf(props, PW_LINK_OUTPUT_PORT_ID, "%d", -1);
|
||||||
|
pw_properties_setf(props, PW_LINK_INPUT_NODE_ID, "%d", session->dsp->info->id);
|
||||||
|
pw_properties_setf(props, PW_LINK_INPUT_PORT_ID, "%d", -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
session->link = pw_core_proxy_create_object(impl->core_proxy,
|
||||||
|
"link-factory",
|
||||||
|
PW_TYPE_INTERFACE_Link,
|
||||||
|
PW_VERSION_LINK,
|
||||||
|
&props->dict,
|
||||||
|
0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int on_node_running(struct impl *impl, struct node *node)
|
||||||
|
{
|
||||||
|
struct session *sess = node->manager;
|
||||||
|
|
||||||
|
if (sess == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (node->type) {
|
||||||
|
case NODE_TYPE_DSP:
|
||||||
|
pw_log_debug(NAME" %p: dsp running for session %d", impl, sess->id);
|
||||||
|
if (sess->link == NULL)
|
||||||
|
link_session_dsp(impl, sess);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NODE_TYPE_DEVICE:
|
||||||
|
pw_log_debug(NAME" %p: device running or session %d", impl, sess->id);
|
||||||
|
remove_idle_timeout(sess);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void node_event_info(void *object, struct pw_node_info *info)
|
static void node_event_info(void *object, struct pw_node_info *info)
|
||||||
{
|
{
|
||||||
struct node *n = object;
|
struct node *n = object;
|
||||||
pw_log_debug(NAME" %p: info for node %d", n->obj.impl, n->obj.id);
|
struct impl *impl = n->obj.impl;
|
||||||
|
|
||||||
|
pw_log_debug(NAME" %p: info for node %d type %d", impl, n->obj.id, n->type);
|
||||||
n->info = pw_node_info_update(n->info, info);
|
n->info = pw_node_info_update(n->info, info);
|
||||||
|
|
||||||
|
switch (info->state) {
|
||||||
|
case PW_NODE_STATE_IDLE:
|
||||||
|
on_node_idle(impl, n);
|
||||||
|
break;
|
||||||
|
case PW_NODE_STATE_RUNNING:
|
||||||
|
on_node_running(impl, n);
|
||||||
|
break;
|
||||||
|
case PW_NODE_STATE_SUSPENDED:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct pw_node_proxy_events node_events = {
|
static const struct pw_node_proxy_events node_events = {
|
||||||
|
|
@ -299,6 +437,7 @@ handle_node(struct impl *impl, uint32_t id, uint32_t parent_id,
|
||||||
|
|
||||||
node->direction = direction;
|
node->direction = direction;
|
||||||
node->type = NODE_TYPE_DEVICE;
|
node->type = NODE_TYPE_DEVICE;
|
||||||
|
node->manager = sess;
|
||||||
|
|
||||||
pw_log_debug(NAME" %p: new session for device node %d", impl, id);
|
pw_log_debug(NAME" %p: new session for device node %d", impl, id);
|
||||||
}
|
}
|
||||||
|
|
@ -432,42 +571,49 @@ registry_global(void *data,uint32_t id, uint32_t parent_id,
|
||||||
schedule_rescan(impl);
|
schedule_rescan(impl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void remove_session(struct impl *impl, struct session *sess)
|
||||||
|
{
|
||||||
|
struct node *n, *t;
|
||||||
|
|
||||||
|
pw_log_debug(NAME " %p: remove session '%d'", impl, sess->id);
|
||||||
|
remove_idle_timeout(sess);
|
||||||
|
|
||||||
|
spa_list_for_each_safe(n, t, &sess->node_list, session_link) {
|
||||||
|
n->session = NULL;
|
||||||
|
spa_list_remove(&n->session_link);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sess->dsp) {
|
||||||
|
pw_log_debug(NAME " %p: destroy dsp", impl);
|
||||||
|
pw_core_proxy_destroy(impl->core_proxy, sess->dsp->obj.proxy);
|
||||||
|
}
|
||||||
|
spa_list_remove(&sess->l);
|
||||||
|
free(sess);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
registry_global_remove(void *data, uint32_t id)
|
registry_global_remove(void *data, uint32_t id)
|
||||||
{
|
{
|
||||||
struct impl *impl = data;
|
struct impl *impl = data;
|
||||||
struct object *obj;
|
struct object *obj;
|
||||||
struct session *sess;
|
|
||||||
|
|
||||||
pw_log_debug(NAME " %p: remove global '%d'", impl, id);
|
pw_log_debug(NAME " %p: remove global '%d'", impl, id);
|
||||||
|
|
||||||
if ((obj = find_object(impl, id)) == NULL)
|
if ((obj = find_object(impl, id)) == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
spa_list_for_each(sess, &impl->session_list, l) {
|
switch (obj->type) {
|
||||||
struct node *node = (struct node *)obj, *n, *t;
|
case PW_TYPE_INTERFACE_Node:
|
||||||
|
{
|
||||||
|
struct node *node = (struct node*) obj;
|
||||||
|
if (node->manager)
|
||||||
|
remove_session(impl, node->manager);
|
||||||
|
break;
|
||||||
|
|
||||||
if (sess->node != node)
|
}
|
||||||
continue;
|
default:
|
||||||
|
|
||||||
pw_log_debug(NAME " %p: remove session '%d'", impl, sess->id);
|
|
||||||
remove_idle_timeout(sess);
|
|
||||||
|
|
||||||
spa_list_for_each_safe(n, t, &sess->node_list, session_link) {
|
|
||||||
n->session = NULL;
|
|
||||||
spa_list_remove(&n->session_link);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sess->dsp) {
|
|
||||||
uint32_t id = ((struct object *)sess->dsp)->id;
|
|
||||||
pw_log_debug(NAME " %p: destroy dsp '%d'", impl, id);
|
|
||||||
pw_core_proxy_destroy(impl->core_proxy, id);
|
|
||||||
}
|
|
||||||
spa_list_remove(&sess->l);
|
|
||||||
free(sess);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
remove_object(impl, obj);
|
remove_object(impl, obj);
|
||||||
schedule_rescan(impl);
|
schedule_rescan(impl);
|
||||||
}
|
}
|
||||||
|
|
@ -479,39 +625,6 @@ static const struct pw_registry_proxy_events registry_events = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static int link_session_dsp(struct session *session)
|
|
||||||
{
|
|
||||||
struct impl *impl = session->impl;
|
|
||||||
struct pw_properties *props;
|
|
||||||
|
|
||||||
pw_log_debug(NAME " %p: link session dsp '%d'", impl, session->id);
|
|
||||||
|
|
||||||
props = pw_properties_new(NULL, NULL);
|
|
||||||
pw_properties_set(props, PW_LINK_PROP_PASSIVE, "true");
|
|
||||||
if (session->direction == PW_DIRECTION_OUTPUT) {
|
|
||||||
pw_properties_setf(props, PW_LINK_OUTPUT_NODE_ID, "%d", session->dsp->info->id);
|
|
||||||
pw_properties_setf(props, PW_LINK_OUTPUT_PORT_ID, "%d", -1);
|
|
||||||
pw_properties_setf(props, PW_LINK_INPUT_NODE_ID, "%d", session->node->info->id);
|
|
||||||
pw_properties_setf(props, PW_LINK_INPUT_PORT_ID, "%d", -1);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
pw_properties_setf(props, PW_LINK_OUTPUT_NODE_ID, "%d", session->node->info->id);
|
|
||||||
pw_properties_setf(props, PW_LINK_OUTPUT_PORT_ID, "%d", -1);
|
|
||||||
pw_properties_setf(props, PW_LINK_INPUT_NODE_ID, "%d", session->dsp->info->id);
|
|
||||||
pw_properties_setf(props, PW_LINK_INPUT_PORT_ID, "%d", -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
session->link = pw_core_proxy_create_object(impl->core_proxy,
|
|
||||||
"link-factory",
|
|
||||||
PW_TYPE_INTERFACE_Link,
|
|
||||||
PW_VERSION_LINK,
|
|
||||||
&props->dict,
|
|
||||||
0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct find_data {
|
struct find_data {
|
||||||
struct impl *impl;
|
struct impl *impl;
|
||||||
uint32_t path_id;
|
uint32_t path_id;
|
||||||
|
|
@ -618,7 +731,6 @@ static int rescan_node(struct impl *impl, struct node *node)
|
||||||
struct pw_node_info *info;
|
struct pw_node_info *info;
|
||||||
struct node *peer;
|
struct node *peer;
|
||||||
enum pw_direction direction;
|
enum pw_direction direction;
|
||||||
int res;
|
|
||||||
|
|
||||||
if (node->type == NODE_TYPE_DSP || node->type == NODE_TYPE_DEVICE)
|
if (node->type == NODE_TYPE_DSP || node->type == NODE_TYPE_DEVICE)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -722,10 +834,6 @@ static int rescan_node(struct impl *impl, struct node *node)
|
||||||
session->exclusive = exclusive;
|
session->exclusive = exclusive;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (session->link == NULL) {
|
|
||||||
if ((res = link_session_dsp(session)) < 0)
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
peer = session->dsp;
|
peer = session->dsp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -734,7 +842,6 @@ static int rescan_node(struct impl *impl, struct node *node)
|
||||||
session->busy = true;
|
session->busy = true;
|
||||||
node->session = session;
|
node->session = session;
|
||||||
spa_list_append(&session->node_list, &node->session_link);
|
spa_list_append(&session->node_list, &node->session_link);
|
||||||
remove_idle_timeout(session);
|
|
||||||
|
|
||||||
link_nodes(peer, direction, node);
|
link_nodes(peer, direction, node);
|
||||||
|
|
||||||
|
|
@ -756,6 +863,7 @@ static void dsp_node_event_info(void *object, struct pw_node_info *info)
|
||||||
|
|
||||||
dsp->direction = s->direction;
|
dsp->direction = s->direction;
|
||||||
dsp->type = NODE_TYPE_DSP;
|
dsp->type = NODE_TYPE_DSP;
|
||||||
|
dsp->manager = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct pw_node_proxy_events dsp_node_events = {
|
static const struct pw_node_proxy_events dsp_node_events = {
|
||||||
|
|
@ -763,36 +871,8 @@ static const struct pw_node_proxy_events dsp_node_events = {
|
||||||
.info = dsp_node_event_info,
|
.info = dsp_node_event_info,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void idle_timeout(void *data, uint64_t expirations)
|
|
||||||
{
|
|
||||||
struct session *sess = data;
|
|
||||||
struct impl *impl = sess->impl;
|
|
||||||
struct spa_command *cmd = &SPA_NODE_COMMAND_INIT(SPA_NODE_COMMAND_Suspend);
|
|
||||||
|
|
||||||
pw_log_debug(NAME " %p: session %d idle timeout", impl, sess->id);
|
|
||||||
|
|
||||||
remove_idle_timeout(sess);
|
|
||||||
|
|
||||||
pw_node_proxy_send_command((struct pw_node_proxy*)sess->node->obj.proxy, cmd);
|
|
||||||
if (sess->dsp)
|
|
||||||
pw_node_proxy_send_command((struct pw_node_proxy*)sess->dsp->obj.proxy, cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void rescan_session(struct impl *impl, struct session *sess)
|
static void rescan_session(struct impl *impl, struct session *sess)
|
||||||
{
|
{
|
||||||
if (spa_list_is_empty(&sess->node_list) && sess->busy) {
|
|
||||||
struct pw_loop *main_loop = pw_core_get_main_loop(impl->core);
|
|
||||||
struct timespec value;
|
|
||||||
|
|
||||||
pw_log_debug(NAME "%p: session %d became idle", impl, sess->id);
|
|
||||||
sess->exclusive = false;
|
|
||||||
sess->busy = false;
|
|
||||||
|
|
||||||
sess->idle_timeout = pw_loop_add_timer(main_loop, idle_timeout, sess);
|
|
||||||
value.tv_sec = 3;
|
|
||||||
value.tv_nsec = 0;
|
|
||||||
pw_loop_update_timer(main_loop, sess->idle_timeout, &value, NULL, false);
|
|
||||||
}
|
|
||||||
if (sess->need_dsp && sess->dsp == NULL && !sess->dsp_pending) {
|
if (sess->need_dsp && sess->dsp == NULL && !sess->dsp_pending) {
|
||||||
struct pw_properties *props;
|
struct pw_properties *props;
|
||||||
struct node *node = sess->node;
|
struct node *node = sess->node;
|
||||||
|
|
|
||||||
|
|
@ -58,8 +58,7 @@ struct pw_client_node_position {
|
||||||
#define PW_CLIENT_NODE_PROXY_METHOD_PORT_UPDATE 2
|
#define PW_CLIENT_NODE_PROXY_METHOD_PORT_UPDATE 2
|
||||||
#define PW_CLIENT_NODE_PROXY_METHOD_SET_ACTIVE 3
|
#define PW_CLIENT_NODE_PROXY_METHOD_SET_ACTIVE 3
|
||||||
#define PW_CLIENT_NODE_PROXY_METHOD_EVENT 4
|
#define PW_CLIENT_NODE_PROXY_METHOD_EVENT 4
|
||||||
#define PW_CLIENT_NODE_PROXY_METHOD_DESTROY 5
|
#define PW_CLIENT_NODE_PROXY_METHOD_NUM 5
|
||||||
#define PW_CLIENT_NODE_PROXY_METHOD_NUM 6
|
|
||||||
|
|
||||||
/** \ref pw_client_node methods */
|
/** \ref pw_client_node methods */
|
||||||
struct pw_client_node_proxy_methods {
|
struct pw_client_node_proxy_methods {
|
||||||
|
|
@ -120,10 +119,6 @@ struct pw_client_node_proxy_methods {
|
||||||
* \param event the event to send
|
* \param event the event to send
|
||||||
*/
|
*/
|
||||||
void (*event) (void *object, struct spa_event *event);
|
void (*event) (void *object, struct spa_event *event);
|
||||||
/**
|
|
||||||
* Destroy the client_node
|
|
||||||
*/
|
|
||||||
void (*destroy) (void *object);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
|
@ -176,13 +171,6 @@ pw_client_node_proxy_event(struct pw_client_node_proxy *p, struct spa_event *eve
|
||||||
pw_proxy_do((struct pw_proxy*)p, struct pw_client_node_proxy_methods, event, event);
|
pw_proxy_do((struct pw_proxy*)p, struct pw_client_node_proxy_methods, event, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
|
||||||
pw_client_node_proxy_destroy(struct pw_client_node_proxy *p)
|
|
||||||
{
|
|
||||||
pw_proxy_do((struct pw_proxy*)p, struct pw_client_node_proxy_methods, destroy);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define PW_CLIENT_NODE_PROXY_EVENT_ADD_MEM 0
|
#define PW_CLIENT_NODE_PROXY_EVENT_ADD_MEM 0
|
||||||
#define PW_CLIENT_NODE_PROXY_EVENT_TRANSPORT 1
|
#define PW_CLIENT_NODE_PROXY_EVENT_TRANSPORT 1
|
||||||
#define PW_CLIENT_NODE_PROXY_EVENT_SET_PARAM 2
|
#define PW_CLIENT_NODE_PROXY_EVENT_SET_PARAM 2
|
||||||
|
|
|
||||||
|
|
@ -1086,12 +1086,6 @@ static void client_node_event(void *data, struct spa_event *event)
|
||||||
this->callbacks->event(this->callbacks_data, event);
|
this->callbacks->event(this->callbacks_data, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void client_node_destroy(void *data)
|
|
||||||
{
|
|
||||||
struct impl *impl = data;
|
|
||||||
pw_client_node_destroy(&impl->this);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct pw_client_node_proxy_methods client_node_methods = {
|
static struct pw_client_node_proxy_methods client_node_methods = {
|
||||||
PW_VERSION_CLIENT_NODE_PROXY_METHODS,
|
PW_VERSION_CLIENT_NODE_PROXY_METHODS,
|
||||||
.done = client_node_done,
|
.done = client_node_done,
|
||||||
|
|
@ -1099,7 +1093,6 @@ static struct pw_client_node_proxy_methods client_node_methods = {
|
||||||
.port_update = client_node_port_update,
|
.port_update = client_node_port_update,
|
||||||
.set_active = client_node_set_active,
|
.set_active = client_node_set_active,
|
||||||
.event = client_node_event,
|
.event = client_node_event,
|
||||||
.destroy = client_node_destroy,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void node_on_data_fd_events(struct spa_source *source)
|
static void node_on_data_fd_events(struct spa_source *source)
|
||||||
|
|
|
||||||
|
|
@ -153,18 +153,6 @@ static void client_node_marshal_event_method(void *object, struct spa_event *eve
|
||||||
pw_protocol_native_end_proxy(proxy, b);
|
pw_protocol_native_end_proxy(proxy, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void client_node_marshal_destroy(void *object)
|
|
||||||
{
|
|
||||||
struct pw_proxy *proxy = object;
|
|
||||||
struct spa_pod_builder *b;
|
|
||||||
|
|
||||||
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_DESTROY);
|
|
||||||
|
|
||||||
spa_pod_builder_add_struct(b);
|
|
||||||
|
|
||||||
pw_protocol_native_end_proxy(proxy, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int client_node_demarshal_add_mem(void *object, void *data, size_t size)
|
static int client_node_demarshal_add_mem(void *object, void *data, size_t size)
|
||||||
{
|
{
|
||||||
struct pw_proxy *proxy = object;
|
struct pw_proxy *proxy = object;
|
||||||
|
|
@ -874,27 +862,13 @@ static int client_node_demarshal_event_method(void *object, void *data, size_t s
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int client_node_demarshal_destroy(void *object, void *data, size_t size)
|
|
||||||
{
|
|
||||||
struct pw_resource *resource = object;
|
|
||||||
struct spa_pod_parser prs;
|
|
||||||
|
|
||||||
spa_pod_parser_init(&prs, data, size, 0);
|
|
||||||
if (spa_pod_parser_get(&prs, "[", NULL) < 0)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
pw_resource_do(resource, struct pw_client_node_proxy_methods, destroy, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct pw_client_node_proxy_methods pw_protocol_native_client_node_method_marshal = {
|
static const struct pw_client_node_proxy_methods pw_protocol_native_client_node_method_marshal = {
|
||||||
PW_VERSION_CLIENT_NODE_PROXY_METHODS,
|
PW_VERSION_CLIENT_NODE_PROXY_METHODS,
|
||||||
&client_node_marshal_done,
|
&client_node_marshal_done,
|
||||||
&client_node_marshal_update,
|
&client_node_marshal_update,
|
||||||
&client_node_marshal_port_update,
|
&client_node_marshal_port_update,
|
||||||
&client_node_marshal_set_active,
|
&client_node_marshal_set_active,
|
||||||
&client_node_marshal_event_method,
|
&client_node_marshal_event_method
|
||||||
&client_node_marshal_destroy
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct pw_protocol_native_demarshal pw_protocol_native_client_node_method_demarshal[] = {
|
static const struct pw_protocol_native_demarshal pw_protocol_native_client_node_method_demarshal[] = {
|
||||||
|
|
@ -902,8 +876,7 @@ static const struct pw_protocol_native_demarshal pw_protocol_native_client_node_
|
||||||
{ &client_node_demarshal_update, 0 },
|
{ &client_node_demarshal_update, 0 },
|
||||||
{ &client_node_demarshal_port_update, 0 },
|
{ &client_node_demarshal_port_update, 0 },
|
||||||
{ &client_node_demarshal_set_active, 0 },
|
{ &client_node_demarshal_set_active, 0 },
|
||||||
{ &client_node_demarshal_event_method, 0 },
|
{ &client_node_demarshal_event_method, 0 }
|
||||||
{ &client_node_demarshal_destroy, 0 },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct pw_client_node_proxy_events pw_protocol_native_client_node_event_marshal = {
|
static const struct pw_client_node_proxy_events pw_protocol_native_client_node_event_marshal = {
|
||||||
|
|
|
||||||
|
|
@ -509,6 +509,22 @@ static int registry_demarshal_bind(void *object, void *data, size_t size)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int registry_demarshal_destroy(void *object, void *data, size_t size)
|
||||||
|
{
|
||||||
|
struct pw_resource *resource = object;
|
||||||
|
struct spa_pod_parser prs;
|
||||||
|
uint32_t id;
|
||||||
|
|
||||||
|
spa_pod_parser_init(&prs, data, size, 0);
|
||||||
|
if (spa_pod_parser_get(&prs,
|
||||||
|
"["
|
||||||
|
"i", &id, NULL) < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
pw_resource_do(resource, struct pw_registry_proxy_methods, destroy, 0, id);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void module_marshal_info(void *object, struct pw_module_info *info)
|
static void module_marshal_info(void *object, struct pw_module_info *info)
|
||||||
{
|
{
|
||||||
struct pw_resource *resource = object;
|
struct pw_resource *resource = object;
|
||||||
|
|
@ -1127,6 +1143,17 @@ static void registry_marshal_bind(void *object, uint32_t id,
|
||||||
pw_protocol_native_end_proxy(proxy, b);
|
pw_protocol_native_end_proxy(proxy, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void registry_marshal_destroy(void *object, uint32_t id)
|
||||||
|
{
|
||||||
|
struct pw_proxy *proxy = object;
|
||||||
|
struct spa_pod_builder *b;
|
||||||
|
|
||||||
|
b = pw_protocol_native_begin_proxy(proxy, PW_REGISTRY_PROXY_METHOD_DESTROY);
|
||||||
|
spa_pod_builder_add_struct(b,
|
||||||
|
"i", id);
|
||||||
|
pw_protocol_native_end_proxy(proxy, b);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct pw_core_proxy_methods pw_protocol_native_core_method_marshal = {
|
static const struct pw_core_proxy_methods pw_protocol_native_core_method_marshal = {
|
||||||
PW_VERSION_CORE_PROXY_METHODS,
|
PW_VERSION_CORE_PROXY_METHODS,
|
||||||
&core_marshal_hello,
|
&core_marshal_hello,
|
||||||
|
|
@ -1177,10 +1204,12 @@ static const struct pw_protocol_marshal pw_protocol_native_core_marshal = {
|
||||||
static const struct pw_registry_proxy_methods pw_protocol_native_registry_method_marshal = {
|
static const struct pw_registry_proxy_methods pw_protocol_native_registry_method_marshal = {
|
||||||
PW_VERSION_REGISTRY_PROXY_METHODS,
|
PW_VERSION_REGISTRY_PROXY_METHODS,
|
||||||
®istry_marshal_bind,
|
®istry_marshal_bind,
|
||||||
|
®istry_marshal_destroy,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct pw_protocol_native_demarshal pw_protocol_native_registry_method_demarshal[] = {
|
static const struct pw_protocol_native_demarshal pw_protocol_native_registry_method_demarshal[] = {
|
||||||
{ ®istry_demarshal_bind, 0, },
|
{ ®istry_demarshal_bind, 0, },
|
||||||
|
{ ®istry_demarshal_destroy, 0, },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct pw_registry_proxy_events pw_protocol_native_registry_event_marshal = {
|
static const struct pw_registry_proxy_events pw_protocol_native_registry_event_marshal = {
|
||||||
|
|
|
||||||
|
|
@ -89,9 +89,38 @@ static void registry_bind(void *object, uint32_t id,
|
||||||
pw_core_resource_remove_id(client->core_resource, new_id);
|
pw_core_resource_remove_id(client->core_resource, new_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void registry_destroy(void *object, uint32_t id)
|
||||||
|
{
|
||||||
|
struct pw_resource *resource = object;
|
||||||
|
struct pw_client *client = resource->client;
|
||||||
|
struct pw_core *core = resource->core;
|
||||||
|
struct pw_global *global;
|
||||||
|
uint32_t permissions;
|
||||||
|
|
||||||
|
if ((global = pw_core_find_global(core, id)) == NULL)
|
||||||
|
goto no_id;
|
||||||
|
|
||||||
|
permissions = pw_global_get_permissions(global, client);
|
||||||
|
|
||||||
|
if (!PW_PERM_IS_X(permissions))
|
||||||
|
goto no_id;
|
||||||
|
|
||||||
|
pw_log_debug("global %p: destroy global id %d", global, id);
|
||||||
|
|
||||||
|
pw_global_destroy(global);
|
||||||
|
return;
|
||||||
|
|
||||||
|
no_id:
|
||||||
|
pw_log_debug("registry %p: no global with id %u to destroy", resource, id);
|
||||||
|
goto exit;
|
||||||
|
exit:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct pw_registry_proxy_methods registry_methods = {
|
static const struct pw_registry_proxy_methods registry_methods = {
|
||||||
PW_VERSION_REGISTRY_PROXY_METHODS,
|
PW_VERSION_REGISTRY_PROXY_METHODS,
|
||||||
.bind = registry_bind
|
.bind = registry_bind,
|
||||||
|
.destroy = registry_destroy
|
||||||
};
|
};
|
||||||
|
|
||||||
static void destroy_registry_resource(void *object)
|
static void destroy_registry_resource(void *object)
|
||||||
|
|
@ -254,16 +283,24 @@ core_create_object(void *object,
|
||||||
static void core_destroy(void *object, uint32_t id)
|
static void core_destroy(void *object, uint32_t id)
|
||||||
{
|
{
|
||||||
struct pw_resource *resource = object;
|
struct pw_resource *resource = object;
|
||||||
struct pw_core *this = resource->core;
|
struct pw_client *client = resource->client;
|
||||||
struct pw_global *global;
|
struct pw_resource *r;
|
||||||
|
|
||||||
pw_log_debug("core %p: destroy %d from resource %p", resource->core, id, resource);
|
pw_log_debug("core %p: destroy %d from resource %p", resource->core, id, resource);
|
||||||
|
|
||||||
global = pw_core_find_global(this, id);
|
if ((r = pw_client_find_resource(client, id)) == NULL)
|
||||||
if (global == NULL)
|
goto no_resource;
|
||||||
return;
|
|
||||||
|
|
||||||
pw_global_destroy(global);
|
pw_resource_destroy(r);
|
||||||
|
|
||||||
|
done:
|
||||||
|
return;
|
||||||
|
|
||||||
|
no_resource:
|
||||||
|
pw_log_error("can't find resouce %d", id);
|
||||||
|
pw_core_resource_error(client->core_resource,
|
||||||
|
resource->id, -EINVAL, "unknown resouce %d", id);
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct pw_core_proxy_methods core_methods = {
|
static const struct pw_core_proxy_methods core_methods = {
|
||||||
|
|
|
||||||
|
|
@ -259,9 +259,9 @@ void pw_global_destroy(struct pw_global *global)
|
||||||
{
|
{
|
||||||
struct pw_core *core = global->core;
|
struct pw_core *core = global->core;
|
||||||
|
|
||||||
|
pw_log_debug("global %p: destroy %u", global, global->id);
|
||||||
global_unregister(global);
|
global_unregister(global);
|
||||||
|
|
||||||
pw_log_debug("global %p: destroy %u", global, global->id);
|
|
||||||
pw_global_events_destroy(global);
|
pw_global_events_destroy(global);
|
||||||
|
|
||||||
pw_map_remove(&core->globals, global->id);
|
pw_map_remove(&core->globals, global->id);
|
||||||
|
|
|
||||||
|
|
@ -172,11 +172,12 @@ struct pw_core_proxy_methods {
|
||||||
uint32_t version,
|
uint32_t version,
|
||||||
const struct spa_dict *props,
|
const struct spa_dict *props,
|
||||||
uint32_t new_id);
|
uint32_t new_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy an object id
|
* Destroy an resource
|
||||||
*
|
*
|
||||||
* \param id the object id to destroy
|
* Destroy the server resource with the given proxy id.
|
||||||
|
*
|
||||||
|
* \param id the client proxy id to destroy
|
||||||
*/
|
*/
|
||||||
void (*destroy) (void *object, uint32_t id);
|
void (*destroy) (void *object, uint32_t id);
|
||||||
};
|
};
|
||||||
|
|
@ -228,9 +229,9 @@ pw_core_proxy_create_object(struct pw_core_proxy *core,
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
pw_core_proxy_destroy(struct pw_core_proxy *core, uint32_t id)
|
pw_core_proxy_destroy(struct pw_core_proxy *core, struct pw_proxy *proxy)
|
||||||
{
|
{
|
||||||
pw_proxy_do((struct pw_proxy*)core, struct pw_core_proxy_methods, destroy, id);
|
pw_proxy_do((struct pw_proxy*)core, struct pw_core_proxy_methods, destroy, pw_proxy_get_id(proxy));
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PW_CORE_PROXY_EVENT_DONE 0
|
#define PW_CORE_PROXY_EVENT_DONE 0
|
||||||
|
|
@ -336,7 +337,8 @@ pw_core_proxy_add_listener(struct pw_core_proxy *core,
|
||||||
* the access permissions on an object.
|
* the access permissions on an object.
|
||||||
*/
|
*/
|
||||||
#define PW_REGISTRY_PROXY_METHOD_BIND 0
|
#define PW_REGISTRY_PROXY_METHOD_BIND 0
|
||||||
#define PW_REGISTRY_PROXY_METHOD_NUM 1
|
#define PW_REGISTRY_PROXY_METHOD_DESTROY 1
|
||||||
|
#define PW_REGISTRY_PROXY_METHOD_NUM 2
|
||||||
|
|
||||||
/** Registry methods */
|
/** Registry methods */
|
||||||
struct pw_registry_proxy_methods {
|
struct pw_registry_proxy_methods {
|
||||||
|
|
@ -355,6 +357,15 @@ struct pw_registry_proxy_methods {
|
||||||
* \param new_id the client proxy to use
|
* \param new_id the client proxy to use
|
||||||
*/
|
*/
|
||||||
void (*bind) (void *object, uint32_t id, uint32_t type, uint32_t version, uint32_t new_id);
|
void (*bind) (void *object, uint32_t id, uint32_t type, uint32_t version, uint32_t new_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to destroy a global object
|
||||||
|
*
|
||||||
|
* Try to destroy the global object.
|
||||||
|
*
|
||||||
|
* \param id the global id to destroy
|
||||||
|
*/
|
||||||
|
void (*destroy) (void *object, uint32_t id);
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Registry */
|
/** Registry */
|
||||||
|
|
@ -369,6 +380,13 @@ pw_registry_proxy_bind(struct pw_registry_proxy *registry,
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
pw_registry_proxy_destroy(struct pw_registry_proxy *registry, uint32_t id)
|
||||||
|
{
|
||||||
|
struct pw_proxy *reg = (struct pw_proxy*)registry;
|
||||||
|
pw_proxy_do(reg, struct pw_registry_proxy_methods, destroy, id);
|
||||||
|
}
|
||||||
|
|
||||||
#define PW_REGISTRY_PROXY_EVENT_GLOBAL 0
|
#define PW_REGISTRY_PROXY_EVENT_GLOBAL 0
|
||||||
#define PW_REGISTRY_PROXY_EVENT_GLOBAL_REMOVE 1
|
#define PW_REGISTRY_PROXY_EVENT_GLOBAL_REMOVE 1
|
||||||
#define PW_REGISTRY_PROXY_EVENT_NUM 2
|
#define PW_REGISTRY_PROXY_EVENT_NUM 2
|
||||||
|
|
|
||||||
|
|
@ -1270,8 +1270,9 @@ static void do_node_init(struct pw_proxy *proxy)
|
||||||
static void node_destroy(void *data)
|
static void node_destroy(void *data)
|
||||||
{
|
{
|
||||||
struct node_data *d = data;
|
struct node_data *d = data;
|
||||||
|
struct pw_remote *remote = d->remote;
|
||||||
pw_log_debug("%p: destroy", d);
|
pw_log_debug("%p: destroy", d);
|
||||||
pw_client_node_proxy_destroy(d->node_proxy);
|
pw_core_proxy_destroy(remote->core_proxy, (struct pw_proxy *)d->node_proxy);
|
||||||
pw_proxy_destroy((struct pw_proxy *)d->node_proxy);
|
pw_proxy_destroy((struct pw_proxy *)d->node_proxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -992,7 +992,7 @@ static bool do_destroy(struct data *data, const char *cmd, char *args, char **er
|
||||||
asprintf(error, "%s: unknown global %d", cmd, id);
|
asprintf(error, "%s: unknown global %d", cmd, id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
pw_core_proxy_destroy(rd->core_proxy, id);
|
pw_registry_proxy_destroy(rd->registry_proxy, id);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue