mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	Implement subscription with a signal
Use a signal for subscription events Work on handling OOM errors and other errors.
This commit is contained in:
		
							parent
							
								
									1b66bbcffd
								
							
						
					
					
						commit
						85d375e4bb
					
				
					 32 changed files with 531 additions and 176 deletions
				
			
		| 
						 | 
				
			
			@ -98,6 +98,17 @@ connection_parse_client_update (PinosConnection *conn, PinosMessageClientUpdate
 | 
			
		|||
    m->props = pinos_serialize_dict_deserialize (p, SPA_PTR_TO_INT (m->props));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
connection_parse_error (PinosConnection *conn, PinosMessageError *m)
 | 
			
		||||
{
 | 
			
		||||
  void *p;
 | 
			
		||||
 | 
			
		||||
  p = conn->in.data;
 | 
			
		||||
  memcpy (m, p, sizeof (PinosMessageError));
 | 
			
		||||
  if (m->error)
 | 
			
		||||
    m->error = SPA_MEMBER (p, SPA_PTR_TO_INT (m->error), const char);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
connection_parse_notify_global (PinosConnection *conn, PinosMessageNotifyGlobal *ng)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -198,6 +209,8 @@ connection_parse_node_info (PinosConnection *conn, PinosMessageNodeInfo *m)
 | 
			
		|||
 | 
			
		||||
    if (m->info->name)
 | 
			
		||||
      m->info->name = SPA_MEMBER (di, SPA_PTR_TO_INT (m->info->name), const char);
 | 
			
		||||
    if (m->info->error)
 | 
			
		||||
      m->info->error = SPA_MEMBER (di, SPA_PTR_TO_INT (m->info->error), const char);
 | 
			
		||||
    if (m->info->props)
 | 
			
		||||
      m->info->props = pinos_serialize_dict_deserialize (di, SPA_PTR_TO_INT (m->info->props));
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -374,6 +387,29 @@ connection_add_client_update (PinosConnection *conn,
 | 
			
		|||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
connection_add_error (PinosConnection *conn,
 | 
			
		||||
                      uint32_t         dest_id,
 | 
			
		||||
                      PinosMessageError *m)
 | 
			
		||||
{
 | 
			
		||||
  size_t len;
 | 
			
		||||
  void *p;
 | 
			
		||||
  PinosMessageError *d;
 | 
			
		||||
 | 
			
		||||
  /* calc len */
 | 
			
		||||
  len = sizeof (PinosMessageError);
 | 
			
		||||
  len += m->error ? strlen (m->error) + 1 : 0;
 | 
			
		||||
 | 
			
		||||
  p = connection_add_message (conn, dest_id, PINOS_MESSAGE_ERROR, len);
 | 
			
		||||
  memcpy (p, m, sizeof (PinosMessageError));
 | 
			
		||||
  d = p;
 | 
			
		||||
 | 
			
		||||
  if (m->error) {
 | 
			
		||||
    strcpy (p, m->error);
 | 
			
		||||
    d->error = SPA_INT_TO_PTR (SPA_PTRDIFF (p, d));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
connection_add_notify_global (PinosConnection *conn,
 | 
			
		||||
                              uint32_t         dest_id,
 | 
			
		||||
| 
						 | 
				
			
			@ -593,6 +629,7 @@ connection_add_node_info (PinosConnection *conn, uint32_t dest_id, PinosMessageN
 | 
			
		|||
  if (m->info) {
 | 
			
		||||
    len += sizeof (PinosNodeInfo);
 | 
			
		||||
    len += m->info->name ? strlen (m->info->name) + 1 : 0;
 | 
			
		||||
    len += m->info->error ? strlen (m->info->error) + 1 : 0;
 | 
			
		||||
    len += pinos_serialize_dict_get_size (m->info->props);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -615,6 +652,12 @@ connection_add_node_info (PinosConnection *conn, uint32_t dest_id, PinosMessageN
 | 
			
		|||
      di->name = SPA_INT_TO_PTR (SPA_PTRDIFF (p, di));
 | 
			
		||||
      p += slen;
 | 
			
		||||
    }
 | 
			
		||||
    if (m->info->error) {
 | 
			
		||||
      slen = strlen (m->info->error) + 1;
 | 
			
		||||
      memcpy (p, m->info->error, slen);
 | 
			
		||||
      di->error = SPA_INT_TO_PTR (SPA_PTRDIFF (p, di));
 | 
			
		||||
      p += slen;
 | 
			
		||||
    }
 | 
			
		||||
    if (m->info->props) {
 | 
			
		||||
      len = pinos_serialize_dict_serialize (p, m->info->props);
 | 
			
		||||
      di->props = SPA_INT_TO_PTR (SPA_PTRDIFF (p, di));
 | 
			
		||||
| 
						 | 
				
			
			@ -952,7 +995,11 @@ pinos_connection_new (int fd)
 | 
			
		|||
  PinosConnection *c;
 | 
			
		||||
 | 
			
		||||
  c = calloc (1, sizeof (PinosConnection));
 | 
			
		||||
  if (c == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  pinos_log_debug ("connection %p: new", c);
 | 
			
		||||
 | 
			
		||||
  c->fd = fd;
 | 
			
		||||
  c->out.buffer_data = malloc (MAX_BUFFER_SIZE);
 | 
			
		||||
  c->out.buffer_maxsize = MAX_BUFFER_SIZE;
 | 
			
		||||
| 
						 | 
				
			
			@ -960,7 +1007,16 @@ pinos_connection_new (int fd)
 | 
			
		|||
  c->in.buffer_maxsize = MAX_BUFFER_SIZE;
 | 
			
		||||
  c->in.update = true;
 | 
			
		||||
 | 
			
		||||
  if (c->out.buffer_data == NULL || c->in.buffer_data == NULL)
 | 
			
		||||
    goto no_mem;
 | 
			
		||||
 | 
			
		||||
  return c;
 | 
			
		||||
 | 
			
		||||
no_mem:
 | 
			
		||||
  free (c->out.buffer_data);
 | 
			
		||||
  free (c->in.buffer_data);
 | 
			
		||||
  free (c);
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
| 
						 | 
				
			
			@ -1069,6 +1125,10 @@ pinos_connection_parse_message (PinosConnection *conn,
 | 
			
		|||
      memcpy (message, conn->in.data, sizeof (PinosMessageNotifyDone));
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PINOS_MESSAGE_ERROR:
 | 
			
		||||
      connection_parse_error (conn, message);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PINOS_MESSAGE_GET_REGISTRY:
 | 
			
		||||
      if (conn->in.size < sizeof (PinosMessageGetRegistry))
 | 
			
		||||
        return false;
 | 
			
		||||
| 
						 | 
				
			
			@ -1265,6 +1325,10 @@ pinos_connection_add_message (PinosConnection  *conn,
 | 
			
		|||
      memcpy (p, message, sizeof (PinosMessageNotifyDone));
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PINOS_MESSAGE_ERROR:
 | 
			
		||||
      connection_add_error (conn, dest_id, message);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PINOS_MESSAGE_GET_REGISTRY:
 | 
			
		||||
      p = connection_add_message (conn, dest_id, type, sizeof (PinosMessageGetRegistry));
 | 
			
		||||
      memcpy (p, message, sizeof (PinosMessageGetRegistry));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,6 +39,7 @@ typedef enum {
 | 
			
		|||
 | 
			
		||||
  PINOS_MESSAGE_SYNC,
 | 
			
		||||
  PINOS_MESSAGE_NOTIFY_DONE,
 | 
			
		||||
  PINOS_MESSAGE_ERROR,
 | 
			
		||||
  PINOS_MESSAGE_GET_REGISTRY,
 | 
			
		||||
  PINOS_MESSAGE_REMOVE_ID,
 | 
			
		||||
  PINOS_MESSAGE_CORE_INFO,
 | 
			
		||||
| 
						 | 
				
			
			@ -103,6 +104,13 @@ typedef struct {
 | 
			
		|||
  uint32_t     seq;
 | 
			
		||||
} PinosMessageNotifyDone;
 | 
			
		||||
 | 
			
		||||
/* PINOS_MESSAGE_ERROR */
 | 
			
		||||
typedef struct {
 | 
			
		||||
  uint32_t     id;
 | 
			
		||||
  SpaResult    res;
 | 
			
		||||
  const char  *error;
 | 
			
		||||
} PinosMessageError;
 | 
			
		||||
 | 
			
		||||
/* PINOS_MESSAGE_GET_REGISTRY */
 | 
			
		||||
typedef struct {
 | 
			
		||||
  uint32_t     seq;
 | 
			
		||||
| 
						 | 
				
			
			@ -148,7 +156,7 @@ typedef struct {
 | 
			
		|||
/* PINOS_MESSAGE_NOTIFY_GLOBAL */
 | 
			
		||||
typedef struct {
 | 
			
		||||
  uint32_t     id;
 | 
			
		||||
  const char * type;
 | 
			
		||||
  const char  *type;
 | 
			
		||||
} PinosMessageNotifyGlobal;
 | 
			
		||||
 | 
			
		||||
/* PINOS_MESSAGE_NOTIFY_GLOBAL_REMOVE */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,9 +37,6 @@ typedef struct {
 | 
			
		|||
  SpaSource source;
 | 
			
		||||
 | 
			
		||||
  bool disconnecting;
 | 
			
		||||
 | 
			
		||||
  PinosSubscriptionFunc  subscribe_func;
 | 
			
		||||
  void                  *subscribe_data;
 | 
			
		||||
} PinosContextImpl;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -112,6 +109,7 @@ core_dispatch_func (void             *object,
 | 
			
		|||
      PinosSubscriptionEvent event;
 | 
			
		||||
 | 
			
		||||
      pinos_log_debug ("got core info %d", type);
 | 
			
		||||
 | 
			
		||||
      if (proxy->user_data == NULL)
 | 
			
		||||
        event = PINOS_SUBSCRIPTION_EVENT_NEW;
 | 
			
		||||
      else
 | 
			
		||||
| 
						 | 
				
			
			@ -119,13 +117,11 @@ core_dispatch_func (void             *object,
 | 
			
		|||
 | 
			
		||||
      proxy->user_data = pinos_core_info_update (proxy->user_data, m->info);
 | 
			
		||||
 | 
			
		||||
      if (impl->subscribe_func) {
 | 
			
		||||
        impl->subscribe_func (this,
 | 
			
		||||
                              event,
 | 
			
		||||
                              proxy->type,
 | 
			
		||||
                              proxy->id,
 | 
			
		||||
                              impl->subscribe_data);
 | 
			
		||||
      }
 | 
			
		||||
      pinos_signal_emit (&this->subscription,
 | 
			
		||||
                         this,
 | 
			
		||||
                         event,
 | 
			
		||||
                         proxy->type,
 | 
			
		||||
                         proxy->id);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case PINOS_MESSAGE_NOTIFY_DONE:
 | 
			
		||||
| 
						 | 
				
			
			@ -136,6 +132,12 @@ core_dispatch_func (void             *object,
 | 
			
		|||
        context_set_state (this, PINOS_CONTEXT_STATE_CONNECTED, NULL);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case PINOS_MESSAGE_ERROR:
 | 
			
		||||
    {
 | 
			
		||||
      PinosMessageError *m = message;
 | 
			
		||||
      context_set_state (this, PINOS_CONTEXT_STATE_ERROR, m->error);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case PINOS_MESSAGE_REMOVE_ID:
 | 
			
		||||
    {
 | 
			
		||||
      PinosMessageRemoveId *m = message;
 | 
			
		||||
| 
						 | 
				
			
			@ -180,13 +182,11 @@ module_dispatch_func (void             *object,
 | 
			
		|||
 | 
			
		||||
      proxy->user_data = pinos_module_info_update (proxy->user_data, m->info);
 | 
			
		||||
 | 
			
		||||
      if (impl->subscribe_func) {
 | 
			
		||||
        impl->subscribe_func (this,
 | 
			
		||||
                              event,
 | 
			
		||||
                              proxy->type,
 | 
			
		||||
                              proxy->id,
 | 
			
		||||
                              impl->subscribe_data);
 | 
			
		||||
      }
 | 
			
		||||
      pinos_signal_emit (&this->subscription,
 | 
			
		||||
                         this,
 | 
			
		||||
                         event,
 | 
			
		||||
                         proxy->type,
 | 
			
		||||
                         proxy->id);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -221,13 +221,11 @@ node_dispatch_func (void             *object,
 | 
			
		|||
 | 
			
		||||
      proxy->user_data = pinos_node_info_update (proxy->user_data, m->info);
 | 
			
		||||
 | 
			
		||||
      if (impl->subscribe_func) {
 | 
			
		||||
        impl->subscribe_func (this,
 | 
			
		||||
                              event,
 | 
			
		||||
                              proxy->type,
 | 
			
		||||
                              proxy->id,
 | 
			
		||||
                              impl->subscribe_data);
 | 
			
		||||
      }
 | 
			
		||||
      pinos_signal_emit (&this->subscription,
 | 
			
		||||
                         this,
 | 
			
		||||
                         event,
 | 
			
		||||
                         proxy->type,
 | 
			
		||||
                         proxy->id);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    default:
 | 
			
		||||
| 
						 | 
				
			
			@ -261,13 +259,11 @@ client_dispatch_func (void             *object,
 | 
			
		|||
 | 
			
		||||
      proxy->user_data = pinos_client_info_update (proxy->user_data, m->info);
 | 
			
		||||
 | 
			
		||||
      if (impl->subscribe_func) {
 | 
			
		||||
        impl->subscribe_func (this,
 | 
			
		||||
                              event,
 | 
			
		||||
                              proxy->type,
 | 
			
		||||
                              proxy->id,
 | 
			
		||||
                              impl->subscribe_data);
 | 
			
		||||
      }
 | 
			
		||||
      pinos_signal_emit (&this->subscription,
 | 
			
		||||
                         this,
 | 
			
		||||
                         event,
 | 
			
		||||
                         proxy->type,
 | 
			
		||||
                         proxy->id);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    default:
 | 
			
		||||
| 
						 | 
				
			
			@ -301,13 +297,11 @@ link_dispatch_func (void             *object,
 | 
			
		|||
 | 
			
		||||
      proxy->user_data = pinos_link_info_update (proxy->user_data, m->info);
 | 
			
		||||
 | 
			
		||||
      if (impl->subscribe_func) {
 | 
			
		||||
        impl->subscribe_func (this,
 | 
			
		||||
                              event,
 | 
			
		||||
                              proxy->type,
 | 
			
		||||
                              proxy->id,
 | 
			
		||||
                              impl->subscribe_data);
 | 
			
		||||
      }
 | 
			
		||||
      pinos_signal_emit (&this->subscription,
 | 
			
		||||
                         this,
 | 
			
		||||
                         event,
 | 
			
		||||
                         proxy->type,
 | 
			
		||||
                         proxy->id);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    default:
 | 
			
		||||
| 
						 | 
				
			
			@ -338,24 +332,32 @@ registry_dispatch_func (void             *object,
 | 
			
		|||
        proxy = pinos_proxy_new (this,
 | 
			
		||||
                                 SPA_ID_INVALID,
 | 
			
		||||
                                 this->uri.node);
 | 
			
		||||
        if (proxy == NULL)
 | 
			
		||||
          goto no_mem;
 | 
			
		||||
        proxy->dispatch_func = node_dispatch_func;
 | 
			
		||||
        proxy->dispatch_data = impl;
 | 
			
		||||
      } else if (!strcmp (ng->type, PINOS_MODULE_URI)) {
 | 
			
		||||
        proxy = pinos_proxy_new (this,
 | 
			
		||||
                                 SPA_ID_INVALID,
 | 
			
		||||
                                 this->uri.module);
 | 
			
		||||
        if (proxy == NULL)
 | 
			
		||||
          goto no_mem;
 | 
			
		||||
        proxy->dispatch_func = module_dispatch_func;
 | 
			
		||||
        proxy->dispatch_data = impl;
 | 
			
		||||
      } else if (!strcmp (ng->type, PINOS_CLIENT_URI)) {
 | 
			
		||||
        proxy = pinos_proxy_new (this,
 | 
			
		||||
                                 SPA_ID_INVALID,
 | 
			
		||||
                                 this->uri.client);
 | 
			
		||||
        if (proxy == NULL)
 | 
			
		||||
          goto no_mem;
 | 
			
		||||
        proxy->dispatch_func = client_dispatch_func;
 | 
			
		||||
        proxy->dispatch_data = impl;
 | 
			
		||||
      } else if (!strcmp (ng->type, PINOS_LINK_URI)) {
 | 
			
		||||
        proxy = pinos_proxy_new (this,
 | 
			
		||||
                                 SPA_ID_INVALID,
 | 
			
		||||
                                 this->uri.link);
 | 
			
		||||
        if (proxy == NULL)
 | 
			
		||||
          goto no_mem;
 | 
			
		||||
        proxy->dispatch_func = link_dispatch_func;
 | 
			
		||||
        proxy->dispatch_data = impl;
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -376,13 +378,11 @@ registry_dispatch_func (void             *object,
 | 
			
		|||
      PinosMessageNotifyGlobalRemove *ng = message;
 | 
			
		||||
      pinos_log_debug ("got global remove %u", ng->id);
 | 
			
		||||
 | 
			
		||||
      if (impl->subscribe_func) {
 | 
			
		||||
        impl->subscribe_func (this,
 | 
			
		||||
                              PINOS_SUBSCRIPTION_EVENT_REMOVE,
 | 
			
		||||
                              SPA_ID_INVALID,
 | 
			
		||||
                              ng->id,
 | 
			
		||||
                              impl->subscribe_data);
 | 
			
		||||
      }
 | 
			
		||||
      pinos_signal_emit (&this->subscription,
 | 
			
		||||
                         this,
 | 
			
		||||
                         PINOS_SUBSCRIPTION_EVENT_REMOVE,
 | 
			
		||||
                         SPA_ID_INVALID,
 | 
			
		||||
                         ng->id);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    default:
 | 
			
		||||
| 
						 | 
				
			
			@ -390,6 +390,9 @@ registry_dispatch_func (void             *object,
 | 
			
		|||
      break;
 | 
			
		||||
  }
 | 
			
		||||
  return SPA_RESULT_OK;
 | 
			
		||||
 | 
			
		||||
no_mem:
 | 
			
		||||
  return SPA_RESULT_NO_MEMORY;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
| 
						 | 
				
			
			@ -477,6 +480,9 @@ pinos_context_new (PinosLoop       *loop,
 | 
			
		|||
  PinosContext *this;
 | 
			
		||||
 | 
			
		||||
  impl = calloc (1, sizeof (PinosContextImpl));
 | 
			
		||||
  if (impl == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  this = &impl->this;
 | 
			
		||||
  pinos_log_debug ("context %p: new", impl);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -484,6 +490,9 @@ pinos_context_new (PinosLoop       *loop,
 | 
			
		|||
 | 
			
		||||
  if (properties == NULL)
 | 
			
		||||
    properties = pinos_properties_new ("application.name", name, NULL);
 | 
			
		||||
  if (properties == NULL)
 | 
			
		||||
    goto no_mem;
 | 
			
		||||
 | 
			
		||||
  pinos_fill_context_properties (properties);
 | 
			
		||||
  this->properties = properties;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -503,9 +512,15 @@ pinos_context_new (PinosLoop       *loop,
 | 
			
		|||
  spa_list_init (&this->proxy_list);
 | 
			
		||||
 | 
			
		||||
  pinos_signal_init (&this->state_changed);
 | 
			
		||||
  pinos_signal_init (&this->subscription);
 | 
			
		||||
  pinos_signal_init (&this->destroy_signal);
 | 
			
		||||
 | 
			
		||||
  return this;
 | 
			
		||||
 | 
			
		||||
no_mem:
 | 
			
		||||
  free (this->name);
 | 
			
		||||
  free (impl);
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
| 
						 | 
				
			
			@ -523,14 +538,10 @@ pinos_context_destroy (PinosContext *context)
 | 
			
		|||
  spa_list_for_each_safe (proxy, t2, &context->proxy_list, link)
 | 
			
		||||
    pinos_proxy_destroy (proxy);
 | 
			
		||||
 | 
			
		||||
  if (context->name)
 | 
			
		||||
    free (context->name);
 | 
			
		||||
  free (context->name);
 | 
			
		||||
  if (context->properties)
 | 
			
		||||
    pinos_properties_free (context->properties);
 | 
			
		||||
 | 
			
		||||
  if (context->error)
 | 
			
		||||
    free (context->error);
 | 
			
		||||
 | 
			
		||||
  free (context->error);
 | 
			
		||||
  free (impl);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -579,8 +590,7 @@ pinos_context_connect (PinosContext      *context)
 | 
			
		|||
  if (name_size > (int)sizeof addr.sun_path) {
 | 
			
		||||
    pinos_log_error ("socket path \"%s/%s\" plus null terminator exceeds 108 bytes",
 | 
			
		||||
                     runtime_dir, name);
 | 
			
		||||
    close (fd);
 | 
			
		||||
    return false;
 | 
			
		||||
    goto error_close;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  size = offsetof (struct sockaddr_un, sun_path) + name_size;
 | 
			
		||||
| 
						 | 
				
			
			@ -589,12 +599,14 @@ pinos_context_connect (PinosContext      *context)
 | 
			
		|||
    context_set_state (context,
 | 
			
		||||
                       PINOS_CONTEXT_STATE_ERROR,
 | 
			
		||||
                       "connect failed: %s", strerror (errno));
 | 
			
		||||
    close (fd);
 | 
			
		||||
    return false;
 | 
			
		||||
    goto error_close;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  impl->fd = fd;
 | 
			
		||||
  impl->connection = pinos_connection_new (fd);
 | 
			
		||||
  if (impl->connection == NULL)
 | 
			
		||||
    goto error_close;
 | 
			
		||||
 | 
			
		||||
  impl->fd = fd;
 | 
			
		||||
 | 
			
		||||
  pinos_loop_add_io (context->loop,
 | 
			
		||||
                     fd,
 | 
			
		||||
| 
						 | 
				
			
			@ -606,6 +618,9 @@ pinos_context_connect (PinosContext      *context)
 | 
			
		|||
  context->core_proxy = pinos_proxy_new (context,
 | 
			
		||||
                                         SPA_ID_INVALID,
 | 
			
		||||
                                         context->uri.core);
 | 
			
		||||
  if (context->core_proxy == NULL)
 | 
			
		||||
    goto no_proxy;
 | 
			
		||||
 | 
			
		||||
  context->core_proxy->dispatch_func = core_dispatch_func;
 | 
			
		||||
  context->core_proxy->dispatch_data = impl;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -618,6 +633,9 @@ pinos_context_connect (PinosContext      *context)
 | 
			
		|||
  context->registry_proxy = pinos_proxy_new (context,
 | 
			
		||||
                                             SPA_ID_INVALID,
 | 
			
		||||
                                             context->uri.registry);
 | 
			
		||||
  if (context->registry_proxy == NULL)
 | 
			
		||||
    goto no_registry;
 | 
			
		||||
 | 
			
		||||
  context->registry_proxy->dispatch_func = registry_dispatch_func;
 | 
			
		||||
  context->registry_proxy->dispatch_data = impl;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -628,6 +646,14 @@ pinos_context_connect (PinosContext      *context)
 | 
			
		|||
                            &grm,
 | 
			
		||||
                            true);
 | 
			
		||||
  return true;
 | 
			
		||||
 | 
			
		||||
no_registry:
 | 
			
		||||
  pinos_proxy_destroy (context->core_proxy);
 | 
			
		||||
no_proxy:
 | 
			
		||||
  pinos_connection_destroy (impl->connection);
 | 
			
		||||
error_close:
 | 
			
		||||
  close (fd);
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -645,6 +671,8 @@ pinos_context_disconnect (PinosContext *context)
 | 
			
		|||
 | 
			
		||||
  impl->disconnecting = true;
 | 
			
		||||
 | 
			
		||||
  pinos_proxy_destroy (context->registry_proxy);
 | 
			
		||||
  pinos_proxy_destroy (context->core_proxy);
 | 
			
		||||
  pinos_connection_destroy (impl->connection);
 | 
			
		||||
  close (impl->fd);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -653,17 +681,6 @@ pinos_context_disconnect (PinosContext *context)
 | 
			
		|||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
pinos_context_subscribe (PinosContext           *context,
 | 
			
		||||
                         PinosSubscriptionFunc   func,
 | 
			
		||||
                         void                   *data)
 | 
			
		||||
{
 | 
			
		||||
  PinosContextImpl *impl = SPA_CONTAINER_OF (context, PinosContextImpl, this);
 | 
			
		||||
 | 
			
		||||
  impl->subscribe_func = func;
 | 
			
		||||
  impl->subscribe_data = data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
pinos_context_get_core_info (PinosContext            *context,
 | 
			
		||||
                             PinosCoreInfoCallback    cb,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,6 +29,7 @@ typedef struct _PinosContext PinosContext;
 | 
			
		|||
#include <pinos/client/map.h>
 | 
			
		||||
#include <pinos/client/loop.h>
 | 
			
		||||
#include <pinos/client/properties.h>
 | 
			
		||||
#include <pinos/client/subscribe.h>
 | 
			
		||||
#include <pinos/client/proxy.h>
 | 
			
		||||
#include <pinos/client/uri.h>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -66,19 +67,25 @@ struct _PinosContext {
 | 
			
		|||
  PinosProxy      *core_proxy;
 | 
			
		||||
  PinosProxy      *registry_proxy;
 | 
			
		||||
 | 
			
		||||
  PinosMap   objects;
 | 
			
		||||
  PinosMap         objects;
 | 
			
		||||
 | 
			
		||||
  SpaList  global_list;
 | 
			
		||||
  SpaList  stream_list;
 | 
			
		||||
  SpaList  proxy_list;
 | 
			
		||||
  SpaList          global_list;
 | 
			
		||||
  SpaList          stream_list;
 | 
			
		||||
  SpaList          proxy_list;
 | 
			
		||||
 | 
			
		||||
  PinosSendFunc      send_func;
 | 
			
		||||
  void              *send_data;
 | 
			
		||||
  PinosSendFunc    send_func;
 | 
			
		||||
  void            *send_data;
 | 
			
		||||
 | 
			
		||||
  PinosContextState state;
 | 
			
		||||
  char *error;
 | 
			
		||||
  PINOS_SIGNAL (state_changed, (PinosListener *listener,
 | 
			
		||||
                                PinosContext  *context));
 | 
			
		||||
  PINOS_SIGNAL (state_changed,  (PinosListener *listener,
 | 
			
		||||
                                 PinosContext  *context));
 | 
			
		||||
 | 
			
		||||
  PINOS_SIGNAL (subscription,   (PinosListener          *listener,
 | 
			
		||||
                                 PinosContext           *context,
 | 
			
		||||
                                 PinosSubscriptionEvent  event,
 | 
			
		||||
                                 uint32_t                type,
 | 
			
		||||
                                 uint32_t                id));
 | 
			
		||||
 | 
			
		||||
  PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
 | 
			
		||||
                                 PinosContext  *context));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -127,7 +127,11 @@ pinos_spa_dict_copy (SpaDict *dict)
 | 
			
		|||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  copy = calloc (1, sizeof (SpaDict));
 | 
			
		||||
  if (copy == NULL)
 | 
			
		||||
    goto no_mem;
 | 
			
		||||
  copy->items = calloc (dict->n_items, sizeof (SpaDictItem));
 | 
			
		||||
  if (copy->items == NULL)
 | 
			
		||||
    goto no_items;
 | 
			
		||||
  copy->n_items = dict->n_items;
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < dict->n_items; i++) {
 | 
			
		||||
| 
						 | 
				
			
			@ -135,6 +139,11 @@ pinos_spa_dict_copy (SpaDict *dict)
 | 
			
		|||
    copy->items[i].value = strdup (dict->items[i].value);
 | 
			
		||||
  }
 | 
			
		||||
  return copy;
 | 
			
		||||
 | 
			
		||||
no_items:
 | 
			
		||||
  free (copy);
 | 
			
		||||
no_mem:
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PinosCoreInfo *
 | 
			
		||||
| 
						 | 
				
			
			@ -148,6 +157,8 @@ pinos_core_info_update (PinosCoreInfo       *info,
 | 
			
		|||
 | 
			
		||||
  if (info == NULL) {
 | 
			
		||||
    info = calloc (1, sizeof (PinosCoreInfo));
 | 
			
		||||
    if (info == NULL)
 | 
			
		||||
      return NULL;
 | 
			
		||||
    change_mask = ~0;
 | 
			
		||||
  } else {
 | 
			
		||||
    change_mask = info->change_mask | update->change_mask;
 | 
			
		||||
| 
						 | 
				
			
			@ -215,6 +226,8 @@ pinos_node_info_update (PinosNodeInfo       *info,
 | 
			
		|||
 | 
			
		||||
  if (info == NULL) {
 | 
			
		||||
    info = calloc (1, sizeof (PinosNodeInfo));
 | 
			
		||||
    if (info == NULL)
 | 
			
		||||
      return NULL;
 | 
			
		||||
    change_mask = ~0;
 | 
			
		||||
  } else {
 | 
			
		||||
    change_mask = info->change_mask | update->change_mask;
 | 
			
		||||
| 
						 | 
				
			
			@ -229,6 +242,9 @@ pinos_node_info_update (PinosNodeInfo       *info,
 | 
			
		|||
  }
 | 
			
		||||
  if (update->change_mask & (1 << 1)) {
 | 
			
		||||
    info->state = update->state;
 | 
			
		||||
    if (info->error)
 | 
			
		||||
      free ((void*)info->error);
 | 
			
		||||
    info->error = update->error ? strdup (update->error) : NULL;
 | 
			
		||||
  }
 | 
			
		||||
  if (update->change_mask & (1 << 2)) {
 | 
			
		||||
    if (info->props)
 | 
			
		||||
| 
						 | 
				
			
			@ -245,6 +261,8 @@ pinos_node_info_free (PinosNodeInfo *info)
 | 
			
		|||
    return;
 | 
			
		||||
  if (info->name)
 | 
			
		||||
    free ((void*)info->name);
 | 
			
		||||
  if (info->error)
 | 
			
		||||
    free ((void*)info->error);
 | 
			
		||||
  if (info->props)
 | 
			
		||||
    pinos_spa_dict_destroy (info->props);
 | 
			
		||||
  free (info);
 | 
			
		||||
| 
						 | 
				
			
			@ -261,6 +279,8 @@ pinos_module_info_update (PinosModuleInfo       *info,
 | 
			
		|||
 | 
			
		||||
  if (info == NULL) {
 | 
			
		||||
    info = calloc (1, sizeof (PinosModuleInfo));
 | 
			
		||||
    if (info == NULL)
 | 
			
		||||
      return NULL;
 | 
			
		||||
    change_mask = ~0;
 | 
			
		||||
  } else {
 | 
			
		||||
    change_mask = info->change_mask | update->change_mask;
 | 
			
		||||
| 
						 | 
				
			
			@ -320,6 +340,8 @@ pinos_client_info_update (PinosClientInfo       *info,
 | 
			
		|||
 | 
			
		||||
  if (info == NULL) {
 | 
			
		||||
    info = calloc (1, sizeof (PinosClientInfo));
 | 
			
		||||
    if (info == NULL)
 | 
			
		||||
      return NULL;
 | 
			
		||||
    change_mask = ~0;
 | 
			
		||||
  } else {
 | 
			
		||||
    change_mask = info->change_mask | update->change_mask;
 | 
			
		||||
| 
						 | 
				
			
			@ -336,7 +358,7 @@ pinos_client_info_update (PinosClientInfo       *info,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
pinos_client_info_free   (PinosClientInfo       *info)
 | 
			
		||||
pinos_client_info_free (PinosClientInfo *info)
 | 
			
		||||
{
 | 
			
		||||
  if (info == NULL)
 | 
			
		||||
    return;
 | 
			
		||||
| 
						 | 
				
			
			@ -356,6 +378,8 @@ pinos_link_info_update (PinosLinkInfo       *info,
 | 
			
		|||
 | 
			
		||||
  if (info == NULL) {
 | 
			
		||||
    info = calloc (1, sizeof (PinosLinkInfo));
 | 
			
		||||
    if (info == NULL)
 | 
			
		||||
      return NULL;
 | 
			
		||||
    change_mask = ~0;
 | 
			
		||||
  } else {
 | 
			
		||||
    change_mask = info->change_mask | update->change_mask;
 | 
			
		||||
| 
						 | 
				
			
			@ -376,7 +400,7 @@ pinos_link_info_update (PinosLinkInfo       *info,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
pinos_link_info_free (PinosLinkInfo       *info)
 | 
			
		||||
pinos_link_info_free (PinosLinkInfo *info)
 | 
			
		||||
{
 | 
			
		||||
  free (info);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -240,18 +240,20 @@ void            pinos_context_get_client_info_by_id (PinosContext            *co
 | 
			
		|||
 * @id: generic id of the node
 | 
			
		||||
 * @change_mask: bitfield of changed fields since last call
 | 
			
		||||
 * @name: name the node, suitable for display
 | 
			
		||||
 * @props: the properties of the node
 | 
			
		||||
 * @state: the current state of the node
 | 
			
		||||
 * @error: an error reason if @state is error
 | 
			
		||||
 * @props: the properties of the node
 | 
			
		||||
 *
 | 
			
		||||
 * The node information. Extra information can be added in later
 | 
			
		||||
 * versions.
 | 
			
		||||
 */
 | 
			
		||||
struct _PinosNodeInfo {
 | 
			
		||||
  uint32_t id;
 | 
			
		||||
  uint64_t change_mask;
 | 
			
		||||
  const char *name;
 | 
			
		||||
  PinosNodeState state;
 | 
			
		||||
  SpaDict *props;
 | 
			
		||||
  uint32_t        id;
 | 
			
		||||
  uint64_t        change_mask;
 | 
			
		||||
  const char     *name;
 | 
			
		||||
  PinosNodeState  state;
 | 
			
		||||
  const char     *error;
 | 
			
		||||
  SpaDict        *props;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
PinosNodeInfo *    pinos_node_info_update (PinosNodeInfo       *info,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -312,6 +312,8 @@ loop_add_io (SpaLoopUtils    *utils,
 | 
			
		|||
  SpaSourceImpl *source;
 | 
			
		||||
 | 
			
		||||
  source = calloc (1, sizeof (SpaSourceImpl));
 | 
			
		||||
  if (source == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  source->source.loop = &impl->loop;
 | 
			
		||||
  source->source.func = source_io_func;
 | 
			
		||||
| 
						 | 
				
			
			@ -353,6 +355,8 @@ loop_add_idle (SpaLoopUtils      *utils,
 | 
			
		|||
  SpaSourceImpl *source;
 | 
			
		||||
 | 
			
		||||
  source = calloc (1, sizeof (SpaSourceImpl));
 | 
			
		||||
  if (source == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  source->source.loop = &impl->loop;
 | 
			
		||||
  source->source.func = source_idle_func;
 | 
			
		||||
| 
						 | 
				
			
			@ -408,6 +412,8 @@ loop_add_event (SpaLoopUtils       *utils,
 | 
			
		|||
  SpaSourceImpl *source;
 | 
			
		||||
 | 
			
		||||
  source = calloc (1, sizeof (SpaSourceImpl));
 | 
			
		||||
  if (source == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  source->source.loop = &impl->loop;
 | 
			
		||||
  source->source.func = source_event_func;
 | 
			
		||||
| 
						 | 
				
			
			@ -454,6 +460,8 @@ loop_add_timer (SpaLoopUtils       *utils,
 | 
			
		|||
  SpaSourceImpl *source;
 | 
			
		||||
 | 
			
		||||
  source = calloc (1, sizeof (SpaSourceImpl));
 | 
			
		||||
  if (source == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  source->source.loop = &impl->loop;
 | 
			
		||||
  source->source.func = source_timer_func;
 | 
			
		||||
| 
						 | 
				
			
			@ -516,6 +524,8 @@ loop_add_signal (SpaLoopUtils        *utils,
 | 
			
		|||
  sigset_t mask;
 | 
			
		||||
 | 
			
		||||
  source = calloc (1, sizeof (SpaSourceImpl));
 | 
			
		||||
  if (source == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  source->source.loop = &impl->loop;
 | 
			
		||||
  source->source.func = source_signal_func;
 | 
			
		||||
| 
						 | 
				
			
			@ -557,13 +567,14 @@ pinos_loop_new (void)
 | 
			
		|||
  PinosLoop *this;
 | 
			
		||||
 | 
			
		||||
  impl = calloc (1, sizeof (PinosLoopImpl));
 | 
			
		||||
  if (impl == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  this = &impl->this;
 | 
			
		||||
 | 
			
		||||
  impl->epoll_fd = epoll_create1 (EPOLL_CLOEXEC);
 | 
			
		||||
  if (impl->epoll_fd == -1) {
 | 
			
		||||
    free (impl);
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
  if (impl->epoll_fd == -1)
 | 
			
		||||
    goto no_epoll;
 | 
			
		||||
 | 
			
		||||
  spa_list_init (&impl->source_list);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -600,6 +611,10 @@ pinos_loop_new (void)
 | 
			
		|||
  spa_ringbuffer_init (&impl->buffer, DATAS_SIZE);
 | 
			
		||||
 | 
			
		||||
  return this;
 | 
			
		||||
 | 
			
		||||
no_epoll:
 | 
			
		||||
  free (impl);
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -91,14 +91,14 @@ pinos_memblock_alloc (PinosMemblockFlags  flags,
 | 
			
		|||
    mem->fd = memfd_create ("pinos-memfd", MFD_CLOEXEC | MFD_ALLOW_SEALING);
 | 
			
		||||
    if (mem->fd == -1) {
 | 
			
		||||
      pinos_log_error ("Failed to create memfd: %s\n", strerror (errno));
 | 
			
		||||
      return SPA_RESULT_ERROR;
 | 
			
		||||
      return SPA_RESULT_ERRNO;
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
    char filename[] = "/dev/shm/spa-tmpfile.XXXXXX";
 | 
			
		||||
    mem->fd = mkostemp (filename, O_CLOEXEC);
 | 
			
		||||
    if (mem->fd == -1) {
 | 
			
		||||
      pinos_log_error ("Failed to create temporary file: %s\n", strerror (errno));
 | 
			
		||||
      return SPA_RESULT_ERROR;
 | 
			
		||||
      return SPA_RESULT_ERRNO;
 | 
			
		||||
    }
 | 
			
		||||
    unlink (filename);
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -106,7 +106,7 @@ pinos_memblock_alloc (PinosMemblockFlags  flags,
 | 
			
		|||
    if (ftruncate (mem->fd, size) < 0) {
 | 
			
		||||
      pinos_log_warn ("Failed to truncate temporary file: %s", strerror (errno));
 | 
			
		||||
      close (mem->fd);
 | 
			
		||||
      return SPA_RESULT_ERROR;
 | 
			
		||||
      return SPA_RESULT_ERRNO;
 | 
			
		||||
    }
 | 
			
		||||
#ifdef USE_MEMFD
 | 
			
		||||
    if (flags & PINOS_MEMBLOCK_FLAG_SEAL) {
 | 
			
		||||
| 
						 | 
				
			
			@ -125,11 +125,15 @@ pinos_memblock_alloc (PinosMemblockFlags  flags,
 | 
			
		|||
        prot |= PROT_WRITE;
 | 
			
		||||
 | 
			
		||||
      mem->ptr = mmap (NULL, size, prot, MAP_SHARED, mem->fd, 0);
 | 
			
		||||
      if (mem->ptr == MAP_FAILED)
 | 
			
		||||
        return SPA_RESULT_NO_MEMORY;
 | 
			
		||||
    } else {
 | 
			
		||||
      mem->ptr = NULL;
 | 
			
		||||
    }
 | 
			
		||||
  } else {
 | 
			
		||||
    mem->ptr = malloc (size);
 | 
			
		||||
    if (mem->ptr == NULL)
 | 
			
		||||
      return SPA_RESULT_NO_MEMORY;
 | 
			
		||||
    mem->fd = -1;
 | 
			
		||||
  }
 | 
			
		||||
  return SPA_RESULT_OK;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -78,6 +78,9 @@ pinos_properties_new (const char *key, ...)
 | 
			
		|||
  const char *value;
 | 
			
		||||
 | 
			
		||||
  impl = calloc (1, sizeof (PinosPropertiesImpl));
 | 
			
		||||
  if (impl == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  pinos_array_init (&impl->items);
 | 
			
		||||
 | 
			
		||||
  va_start (varargs, key);
 | 
			
		||||
| 
						 | 
				
			
			@ -106,6 +109,9 @@ pinos_properties_new_dict (const SpaDict *dict)
 | 
			
		|||
  PinosPropertiesImpl *impl;
 | 
			
		||||
 | 
			
		||||
  impl = calloc (1, sizeof (PinosPropertiesImpl));
 | 
			
		||||
  if (impl == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  pinos_array_init (&impl->items);
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < dict->n_items; i++)
 | 
			
		||||
| 
						 | 
				
			
			@ -130,6 +136,9 @@ pinos_properties_copy (PinosProperties *properties)
 | 
			
		|||
  SpaDictItem *item;
 | 
			
		||||
 | 
			
		||||
  copy = pinos_properties_new (NULL, NULL);
 | 
			
		||||
  if (copy == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  pinos_array_for_each (item, &impl->items)
 | 
			
		||||
    add_func (copy, strdup (item->key), strdup (item->value));
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -154,6 +163,9 @@ pinos_properties_merge (PinosProperties *oldprops,
 | 
			
		|||
    void * state = NULL;
 | 
			
		||||
 | 
			
		||||
    res = pinos_properties_copy (oldprops);
 | 
			
		||||
    if (res == NULL)
 | 
			
		||||
      return NULL;
 | 
			
		||||
 | 
			
		||||
    while ((key = pinos_properties_iterate (newprops, &state))) {
 | 
			
		||||
       pinos_properties_set (res,
 | 
			
		||||
                             key,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,6 +33,9 @@ pinos_proxy_new (PinosContext *context,
 | 
			
		|||
  PinosProxy *this;
 | 
			
		||||
 | 
			
		||||
  impl = calloc (1, sizeof (PinosProxyImpl));
 | 
			
		||||
  if (impl == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  this = &impl->this;
 | 
			
		||||
 | 
			
		||||
  this->context = context;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -64,6 +64,9 @@ pinos_rtkit_bus_get_system (void)
 | 
			
		|||
  dbus_error_init(&error);
 | 
			
		||||
 | 
			
		||||
  bus = calloc (1, sizeof (PinosRTKitBus));
 | 
			
		||||
  if (bus == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  bus->bus = dbus_bus_get_private (DBUS_BUS_SYSTEM, &error);
 | 
			
		||||
  if (bus->bus == NULL)
 | 
			
		||||
    goto error;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -173,19 +173,25 @@ pinos_stream_new (PinosContext    *context,
 | 
			
		|||
  PinosStream *this;
 | 
			
		||||
 | 
			
		||||
  impl = calloc (1, sizeof (PinosStreamImpl));
 | 
			
		||||
  if (impl == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  this = &impl->this;
 | 
			
		||||
  pinos_log_debug ("stream %p: new", impl);
 | 
			
		||||
 | 
			
		||||
  this->context = context;
 | 
			
		||||
  this->name = strdup (name);
 | 
			
		||||
 | 
			
		||||
  if (props == NULL) {
 | 
			
		||||
    props = pinos_properties_new ("media.name", name, NULL);
 | 
			
		||||
  } else if (!pinos_properties_get (props, "media.name")) {
 | 
			
		||||
    pinos_properties_set (props, "media.name", name);
 | 
			
		||||
  }
 | 
			
		||||
  if (props == NULL)
 | 
			
		||||
    goto no_mem;
 | 
			
		||||
 | 
			
		||||
  this->properties = props;
 | 
			
		||||
 | 
			
		||||
  this->context = context;
 | 
			
		||||
  this->name = strdup (name);
 | 
			
		||||
 | 
			
		||||
  pinos_signal_init (&this->destroy_signal);
 | 
			
		||||
  pinos_signal_init (&this->state_changed);
 | 
			
		||||
  pinos_signal_init (&this->format_changed);
 | 
			
		||||
| 
						 | 
				
			
			@ -206,6 +212,10 @@ pinos_stream_new (PinosContext    *context,
 | 
			
		|||
  spa_list_insert (&context->stream_list, &this->link);
 | 
			
		||||
 | 
			
		||||
  return this;
 | 
			
		||||
 | 
			
		||||
no_mem:
 | 
			
		||||
  free (impl);
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,16 +48,6 @@ typedef enum {
 | 
			
		|||
    PINOS_SUBSCRIPTION_EVENT_REMOVE        = 2,
 | 
			
		||||
} PinosSubscriptionEvent;
 | 
			
		||||
 | 
			
		||||
typedef void (*PinosSubscriptionFunc)  (PinosContext           *context,
 | 
			
		||||
                                        PinosSubscriptionEvent  event,
 | 
			
		||||
                                        uint32_t                type,
 | 
			
		||||
                                        uint32_t                id,
 | 
			
		||||
                                        void                   *data);
 | 
			
		||||
 | 
			
		||||
void         pinos_context_subscribe  (PinosContext           *context,
 | 
			
		||||
                                       PinosSubscriptionFunc   func,
 | 
			
		||||
                                       void                   *data);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -83,12 +83,14 @@ pinos_thread_main_loop_new (PinosLoop  *loop,
 | 
			
		|||
  pthread_mutexattr_t attr;
 | 
			
		||||
 | 
			
		||||
  impl = calloc (1, sizeof (PinosThreadMainLoopImpl));
 | 
			
		||||
  if (impl == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  this = &impl->this;
 | 
			
		||||
  pinos_log_debug ("thread-mainloop %p: new", impl);
 | 
			
		||||
 | 
			
		||||
  this->loop = loop;
 | 
			
		||||
  if (name)
 | 
			
		||||
    this->name = strdup (name);
 | 
			
		||||
  this->name = name ? strdup (name) : NULL;
 | 
			
		||||
 | 
			
		||||
  pinos_loop_set_hooks (loop,
 | 
			
		||||
                        pre_hook,
 | 
			
		||||
| 
						 | 
				
			
			@ -97,7 +99,6 @@ pinos_thread_main_loop_new (PinosLoop  *loop,
 | 
			
		|||
 | 
			
		||||
  pinos_signal_init (&this->destroy_signal);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  pthread_mutexattr_init (&attr);
 | 
			
		||||
  pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
 | 
			
		||||
  pthread_mutex_init (&impl->lock, &attr);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -99,6 +99,9 @@ pinos_transport_new (unsigned int max_inputs,
 | 
			
		|||
  area.n_outputs = 0;
 | 
			
		||||
 | 
			
		||||
  impl = calloc (1, sizeof (PinosTransportImpl));
 | 
			
		||||
  if (impl == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  impl->offset = 0;
 | 
			
		||||
 | 
			
		||||
  trans = &impl->trans;
 | 
			
		||||
| 
						 | 
				
			
			@ -124,6 +127,9 @@ pinos_transport_new_from_info (PinosTransportInfo *info)
 | 
			
		|||
  void *tmp;
 | 
			
		||||
 | 
			
		||||
  impl = calloc (1, sizeof (PinosTransportImpl));
 | 
			
		||||
  if (impl == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  trans = &impl->trans;
 | 
			
		||||
  pinos_signal_init (&trans->destroy_signal);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -254,14 +254,14 @@ find_device (GstDeviceProvider *provider, uint32_t id)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
context_subscribe_cb (PinosContext           *context,
 | 
			
		||||
                      PinosSubscriptionEvent  event,
 | 
			
		||||
                      uint32_t                type,
 | 
			
		||||
                      uint32_t                id,
 | 
			
		||||
                      void                   *user_data)
 | 
			
		||||
on_context_subscription (PinosListener          *listener,
 | 
			
		||||
                         PinosContext           *context,
 | 
			
		||||
                         PinosSubscriptionEvent  event,
 | 
			
		||||
                         uint32_t                type,
 | 
			
		||||
                         uint32_t                id)
 | 
			
		||||
{
 | 
			
		||||
  GstPinosDeviceProvider *self = user_data;
 | 
			
		||||
  GstDeviceProvider *provider = user_data;
 | 
			
		||||
  GstPinosDeviceProvider *self = SPA_CONTAINER_OF (listener, GstPinosDeviceProvider, ctx_subscription);
 | 
			
		||||
  GstDeviceProvider *provider = GST_DEVICE_PROVIDER (self);
 | 
			
		||||
  GstPinosDevice *dev;
 | 
			
		||||
 | 
			
		||||
  if (type != context->uri.node)
 | 
			
		||||
| 
						 | 
				
			
			@ -442,11 +442,12 @@ gst_pinos_device_provider_start (GstDeviceProvider * provider)
 | 
			
		|||
    goto failed_context;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  pinos_signal_add (&self->context->state_changed, &self->ctx_state_changed, on_context_state_changed);
 | 
			
		||||
 | 
			
		||||
  pinos_context_subscribe (self->context,
 | 
			
		||||
                           context_subscribe_cb,
 | 
			
		||||
                           self);
 | 
			
		||||
  pinos_signal_add (&self->context->state_changed,
 | 
			
		||||
                    &self->ctx_state_changed,
 | 
			
		||||
                    on_context_state_changed);
 | 
			
		||||
  pinos_signal_add (&self->context->subscription,
 | 
			
		||||
                    &self->ctx_subscription,
 | 
			
		||||
                    on_context_subscription);
 | 
			
		||||
 | 
			
		||||
  pinos_context_connect (self->context);
 | 
			
		||||
  for (;;) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -85,6 +85,7 @@ struct _GstPinosDeviceProvider {
 | 
			
		|||
 | 
			
		||||
  PinosContext *context;
 | 
			
		||||
  PinosListener ctx_state_changed;
 | 
			
		||||
  PinosListener ctx_subscription;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _GstPinosDeviceProviderClass {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -111,28 +111,31 @@ on_link_state_changed (PinosListener *listener,
 | 
			
		|||
  switch (state) {
 | 
			
		||||
    case PINOS_LINK_STATE_ERROR:
 | 
			
		||||
    {
 | 
			
		||||
      PinosResource *resource;
 | 
			
		||||
 | 
			
		||||
      pinos_log_debug ("module %p: link %p: state error: %s", impl, link, link->error);
 | 
			
		||||
 | 
			
		||||
      spa_list_for_each (resource, &link->resource_list, link) {
 | 
			
		||||
        pinos_resource_send_error (resource,
 | 
			
		||||
                                   SPA_RESULT_ERROR,
 | 
			
		||||
                                   link->error);
 | 
			
		||||
      }
 | 
			
		||||
#if 0
 | 
			
		||||
      if (link->input && link->input->node)
 | 
			
		||||
        pinos_node_update_state (link->input->node, PINOS_NODE_STATE_ERROR, strdup (link->error));
 | 
			
		||||
      if (link->output && link->output->node)
 | 
			
		||||
        pinos_node_update_state (link->output->node, PINOS_NODE_STATE_ERROR, strdup (link->error));
 | 
			
		||||
#endif
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    case PINOS_LINK_STATE_UNLINKED:
 | 
			
		||||
      pinos_log_debug ("module %p: link %p: unlinked", impl, link);
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
      g_set_error (&error,
 | 
			
		||||
                   PINOS_ERROR,
 | 
			
		||||
                   PINOS_ERROR_NODE_LINK,
 | 
			
		||||
                   "error node unlinked");
 | 
			
		||||
 | 
			
		||||
      if (link->input && link->input->node)
 | 
			
		||||
        pinos_node_report_error (link->input->node, g_error_copy (error));
 | 
			
		||||
        pinos_node_update_state (link->input->node, PINOS_NODE_STATE_ERROR, strdup ("node unlinked"));
 | 
			
		||||
      if (link->output && link->output->node)
 | 
			
		||||
        pinos_node_report_error (link->output->node, g_error_copy (error));
 | 
			
		||||
        pinos_node_update_state (link->output->node, PINOS_NODE_STATE_ERROR, strdup ("node unlinked"));
 | 
			
		||||
#endif
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1234,6 +1234,9 @@ pinos_client_node_new (PinosClient     *client,
 | 
			
		|||
  PinosClientNode *this;
 | 
			
		||||
 | 
			
		||||
  impl = calloc (1, sizeof (PinosClientNodeImpl));
 | 
			
		||||
  if (impl == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  this = &impl->this;
 | 
			
		||||
  impl->core = client->core;
 | 
			
		||||
  impl->data_fd = -1;
 | 
			
		||||
| 
						 | 
				
			
			@ -1248,6 +1251,8 @@ pinos_client_node_new (PinosClient     *client,
 | 
			
		|||
                               &impl->proxy.node,
 | 
			
		||||
                               NULL,
 | 
			
		||||
                               properties);
 | 
			
		||||
  if (this->node == NULL)
 | 
			
		||||
    goto error_no_node;
 | 
			
		||||
 | 
			
		||||
  impl->proxy.pnode = this->node;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1264,12 +1269,21 @@ pinos_client_node_new (PinosClient     *client,
 | 
			
		|||
                                       client->core->uri.client_node,
 | 
			
		||||
                                       this,
 | 
			
		||||
                                       (PinosDestroy) client_node_resource_destroy);
 | 
			
		||||
  impl->proxy.resource = this->resource;
 | 
			
		||||
  if (this->resource == NULL)
 | 
			
		||||
    goto error_no_resource;
 | 
			
		||||
 | 
			
		||||
  impl->proxy.resource = this->resource;
 | 
			
		||||
  this->resource->dispatch_func = client_node_dispatch_func;
 | 
			
		||||
  this->resource->dispatch_data = this;
 | 
			
		||||
 | 
			
		||||
  return this;
 | 
			
		||||
 | 
			
		||||
error_no_resource:
 | 
			
		||||
  pinos_node_destroy (this->node);
 | 
			
		||||
error_no_node:
 | 
			
		||||
  proxy_clear (&impl->proxy);
 | 
			
		||||
  free (impl);
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -69,6 +69,8 @@ client_bind_func (PinosGlobal *global,
 | 
			
		|||
                                 global->core->uri.client,
 | 
			
		||||
                                 global->object,
 | 
			
		||||
                                 client_unbind_func);
 | 
			
		||||
  if (resource == NULL)
 | 
			
		||||
    goto no_mem;
 | 
			
		||||
 | 
			
		||||
  resource->dispatch_func = client_dispatch_func;
 | 
			
		||||
  resource->dispatch_data = global;
 | 
			
		||||
| 
						 | 
				
			
			@ -86,6 +88,12 @@ client_bind_func (PinosGlobal *global,
 | 
			
		|||
                               PINOS_MESSAGE_CLIENT_INFO,
 | 
			
		||||
                               &m,
 | 
			
		||||
                               true);
 | 
			
		||||
  return;
 | 
			
		||||
 | 
			
		||||
no_mem:
 | 
			
		||||
  pinos_resource_send_error (client->core_resource,
 | 
			
		||||
                             SPA_RESULT_NO_MEMORY,
 | 
			
		||||
                             "no memory");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -105,6 +113,9 @@ pinos_client_new (PinosCore       *core,
 | 
			
		|||
  PinosClientImpl *impl;
 | 
			
		||||
 | 
			
		||||
  impl = calloc (1, sizeof (PinosClientImpl));
 | 
			
		||||
  if (impl == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  pinos_log_debug ("client %p: new", impl);
 | 
			
		||||
 | 
			
		||||
  this = &impl->this;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -68,6 +68,8 @@ parse_command_module_load (const char * line, char ** err)
 | 
			
		|||
  PinosCommandImpl *impl;
 | 
			
		||||
 | 
			
		||||
  impl = calloc (1, sizeof (PinosCommandImpl));
 | 
			
		||||
  if (impl == NULL)
 | 
			
		||||
    goto no_mem;
 | 
			
		||||
 | 
			
		||||
  impl->func = execute_command_module_load;
 | 
			
		||||
  impl->args = pinos_split_strv (line, whitespace, 3, &impl->n_args);
 | 
			
		||||
| 
						 | 
				
			
			@ -83,6 +85,9 @@ no_module:
 | 
			
		|||
  asprintf (err, "%s requires a module name", impl->args[0]);
 | 
			
		||||
  pinos_free_strv (impl->args);
 | 
			
		||||
  return NULL;
 | 
			
		||||
no_mem:
 | 
			
		||||
  asprintf (err, "no memory");
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool
 | 
			
		||||
| 
						 | 
				
			
			@ -125,7 +130,7 @@ pinos_command_free (PinosCommand * command)
 | 
			
		|||
 * Returns: The command or %NULL when @err is set.
 | 
			
		||||
 */
 | 
			
		||||
PinosCommand *
 | 
			
		||||
pinos_command_parse (const char     *line,
 | 
			
		||||
pinos_command_parse (const char    *line,
 | 
			
		||||
                     char         **err)
 | 
			
		||||
{
 | 
			
		||||
  PinosCommand *command = NULL;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -51,15 +51,19 @@ registry_dispatch_func (void             *object,
 | 
			
		|||
          break;
 | 
			
		||||
 | 
			
		||||
      if (&global->link == &this->global_list) {
 | 
			
		||||
        pinos_log_error ("unknown object id %d", m->id);
 | 
			
		||||
        pinos_resource_send_error (resource,
 | 
			
		||||
                                   SPA_RESULT_INVALID_OBJECT_ID,
 | 
			
		||||
                                   "unknown object id %u", m->id);
 | 
			
		||||
        return SPA_RESULT_ERROR;
 | 
			
		||||
      }
 | 
			
		||||
      if (global->bind == NULL) {
 | 
			
		||||
        pinos_log_error ("can't bind object id %d", m->id);
 | 
			
		||||
        pinos_resource_send_error (resource,
 | 
			
		||||
                                   SPA_RESULT_NOT_IMPLEMENTED,
 | 
			
		||||
                                   "can't bind object id %d", m->id);
 | 
			
		||||
        return SPA_RESULT_ERROR;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      pinos_log_error ("global %p: bind object id %d", global, m->id);
 | 
			
		||||
      pinos_log_debug ("global %p: bind object id %d", global, m->id);
 | 
			
		||||
      global->bind (global, client, 0, m->id);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -109,6 +113,8 @@ core_dispatch_func (void             *object,
 | 
			
		|||
                                              this->uri.registry,
 | 
			
		||||
                                              this,
 | 
			
		||||
                                              destroy_registry_resource);
 | 
			
		||||
      if (registry_resource == NULL)
 | 
			
		||||
        goto no_mem;
 | 
			
		||||
 | 
			
		||||
      registry_resource->dispatch_func = registry_dispatch_func;
 | 
			
		||||
      registry_resource->dispatch_data = this;
 | 
			
		||||
| 
						 | 
				
			
			@ -142,6 +148,9 @@ core_dispatch_func (void             *object,
 | 
			
		|||
      PinosProperties *props;
 | 
			
		||||
 | 
			
		||||
      props = pinos_properties_new (NULL, NULL);
 | 
			
		||||
      if (props == NULL)
 | 
			
		||||
        goto no_mem;
 | 
			
		||||
 | 
			
		||||
      for (i = 0; i < m->props->n_items; i++) {
 | 
			
		||||
        pinos_properties_set (props, m->props->items[i].key,
 | 
			
		||||
                                     m->props->items[i].value);
 | 
			
		||||
| 
						 | 
				
			
			@ -151,9 +160,13 @@ core_dispatch_func (void             *object,
 | 
			
		|||
                                    m->new_id,
 | 
			
		||||
                                    m->name,
 | 
			
		||||
                                    props);
 | 
			
		||||
      if (node == NULL)
 | 
			
		||||
        goto no_mem;
 | 
			
		||||
 | 
			
		||||
      if ((res = pinos_client_node_get_data_socket (node, &data_fd)) < 0) {
 | 
			
		||||
        pinos_log_error ("can't get data fd");
 | 
			
		||||
        pinos_resource_send_error (resource,
 | 
			
		||||
                                   SPA_RESULT_ERROR,
 | 
			
		||||
                                   "can't get data fd");
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -170,6 +183,12 @@ core_dispatch_func (void             *object,
 | 
			
		|||
      break;
 | 
			
		||||
  }
 | 
			
		||||
  return SPA_RESULT_OK;
 | 
			
		||||
 | 
			
		||||
no_mem:
 | 
			
		||||
  pinos_resource_send_error (resource,
 | 
			
		||||
                             SPA_RESULT_NO_MEMORY,
 | 
			
		||||
                             "no memory");
 | 
			
		||||
  return SPA_RESULT_NO_MEMORY;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
| 
						 | 
				
			
			@ -188,6 +207,8 @@ core_bind_func (PinosGlobal *global,
 | 
			
		|||
                                 global->core->uri.core,
 | 
			
		||||
                                 global->object,
 | 
			
		||||
                                 NULL);
 | 
			
		||||
  if (resource == NULL)
 | 
			
		||||
    goto no_mem;
 | 
			
		||||
 | 
			
		||||
  resource->dispatch_func = core_dispatch_func;
 | 
			
		||||
  resource->dispatch_data = this;
 | 
			
		||||
| 
						 | 
				
			
			@ -211,6 +232,10 @@ core_bind_func (PinosGlobal *global,
 | 
			
		|||
                               PINOS_MESSAGE_CORE_INFO,
 | 
			
		||||
                               &m,
 | 
			
		||||
                               true);
 | 
			
		||||
  return;
 | 
			
		||||
 | 
			
		||||
no_mem:
 | 
			
		||||
  pinos_log_error ("can't create core resource");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PinosCore *
 | 
			
		||||
| 
						 | 
				
			
			@ -220,14 +245,19 @@ pinos_core_new (PinosMainLoop *main_loop)
 | 
			
		|||
  PinosCore *this;
 | 
			
		||||
 | 
			
		||||
  impl = calloc (1, sizeof (PinosCoreImpl));
 | 
			
		||||
  if (impl == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  this = &impl->this;
 | 
			
		||||
  pinos_uri_init (&this->uri);
 | 
			
		||||
 | 
			
		||||
  pinos_map_init (&this->objects, 512);
 | 
			
		||||
 | 
			
		||||
  this->data_loop = pinos_data_loop_new ();
 | 
			
		||||
  if (this->data_loop == NULL)
 | 
			
		||||
    goto no_data_loop;
 | 
			
		||||
 | 
			
		||||
  this->main_loop = main_loop;
 | 
			
		||||
 | 
			
		||||
  pinos_uri_init (&this->uri);
 | 
			
		||||
  pinos_map_init (&this->objects, 512);
 | 
			
		||||
 | 
			
		||||
  impl->support[0].uri = SPA_ID_MAP_URI;
 | 
			
		||||
  impl->support[0].data = this->uri.map;
 | 
			
		||||
  impl->support[1].uri = SPA_LOG_URI;
 | 
			
		||||
| 
						 | 
				
			
			@ -266,6 +296,10 @@ pinos_core_new (PinosMainLoop *main_loop)
 | 
			
		|||
                                        core_bind_func);
 | 
			
		||||
 | 
			
		||||
  return this;
 | 
			
		||||
 | 
			
		||||
no_data_loop:
 | 
			
		||||
  free (impl);
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
| 
						 | 
				
			
			@ -292,6 +326,9 @@ pinos_core_add_global (PinosCore           *core,
 | 
			
		|||
  PinosMessageNotifyGlobal ng;
 | 
			
		||||
 | 
			
		||||
  global = calloc (1, sizeof (PinosGlobal));
 | 
			
		||||
  if (global == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  global->core = core;
 | 
			
		||||
  global->type = type;
 | 
			
		||||
  global->version = version;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -131,16 +131,26 @@ pinos_data_loop_new (void)
 | 
			
		|||
  PinosDataLoop *this;
 | 
			
		||||
 | 
			
		||||
  impl = calloc (1, sizeof (PinosDataLoopImpl));
 | 
			
		||||
  if (impl == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  pinos_log_debug ("data-loop %p: new", impl);
 | 
			
		||||
 | 
			
		||||
  this = &impl->this;
 | 
			
		||||
  this->loop = pinos_loop_new ();
 | 
			
		||||
  if (this->loop == NULL)
 | 
			
		||||
    goto no_loop;
 | 
			
		||||
 | 
			
		||||
  pinos_signal_init (&this->destroy_signal);
 | 
			
		||||
 | 
			
		||||
  impl->event = pinos_loop_add_event (this->loop,
 | 
			
		||||
                                      do_stop,
 | 
			
		||||
                                      impl);
 | 
			
		||||
  return this;
 | 
			
		||||
 | 
			
		||||
no_loop:
 | 
			
		||||
  free (impl);
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,29 +49,24 @@ typedef struct
 | 
			
		|||
} PinosLinkImpl;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
pinos_link_update_state (PinosLink *link, PinosLinkState state)
 | 
			
		||||
pinos_link_update_state (PinosLink      *link,
 | 
			
		||||
                         PinosLinkState  state,
 | 
			
		||||
                         char           *error)
 | 
			
		||||
{
 | 
			
		||||
  if (state != link->state) {
 | 
			
		||||
    free (link->error);
 | 
			
		||||
    link->error = NULL;
 | 
			
		||||
    pinos_log_debug ("link %p: update state %s -> %s", link,
 | 
			
		||||
        pinos_link_state_as_string (link->state),
 | 
			
		||||
        pinos_link_state_as_string (state));
 | 
			
		||||
 | 
			
		||||
    link->state = state;
 | 
			
		||||
    if (link->error)
 | 
			
		||||
      free (link->error);
 | 
			
		||||
    link->error = error;
 | 
			
		||||
 | 
			
		||||
    pinos_signal_emit (&link->core->link_state_changed, link);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
pinos_link_report_error (PinosLink *link, char *error)
 | 
			
		||||
{
 | 
			
		||||
  free (link->error);
 | 
			
		||||
  link->error = error;
 | 
			
		||||
  link->state = PINOS_LINK_STATE_ERROR;
 | 
			
		||||
  pinos_log_debug ("link %p: got error state %s", link, error);
 | 
			
		||||
  pinos_signal_emit (&link->core->link_state_changed, link);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static SpaResult
 | 
			
		||||
do_negotiate (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -83,7 +78,7 @@ do_negotiate (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state)
 | 
			
		|||
  if (in_state != SPA_NODE_STATE_CONFIGURE && out_state != SPA_NODE_STATE_CONFIGURE)
 | 
			
		||||
    return SPA_RESULT_OK;
 | 
			
		||||
 | 
			
		||||
  pinos_link_update_state (this, PINOS_LINK_STATE_NEGOTIATING);
 | 
			
		||||
  pinos_link_update_state (this, PINOS_LINK_STATE_NEGOTIATING, NULL);
 | 
			
		||||
 | 
			
		||||
  /* both ports need a format */
 | 
			
		||||
  if (in_state == SPA_NODE_STATE_CONFIGURE && out_state == SPA_NODE_STATE_CONFIGURE) {
 | 
			
		||||
| 
						 | 
				
			
			@ -170,7 +165,7 @@ again:
 | 
			
		|||
 | 
			
		||||
error:
 | 
			
		||||
  {
 | 
			
		||||
    pinos_link_report_error (this, error);
 | 
			
		||||
    pinos_link_update_state (this, PINOS_LINK_STATE_ERROR, error);
 | 
			
		||||
    return res;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -352,7 +347,7 @@ do_allocation (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state)
 | 
			
		|||
  if (in_state != SPA_NODE_STATE_READY && out_state != SPA_NODE_STATE_READY)
 | 
			
		||||
    return SPA_RESULT_OK;
 | 
			
		||||
 | 
			
		||||
  pinos_link_update_state (this, PINOS_LINK_STATE_ALLOCATING);
 | 
			
		||||
  pinos_link_update_state (this, PINOS_LINK_STATE_ALLOCATING, NULL);
 | 
			
		||||
 | 
			
		||||
  pinos_log_debug ("link %p: doing alloc buffers %p %p", this, this->output->node, this->input->node);
 | 
			
		||||
  /* find out what's possible */
 | 
			
		||||
| 
						 | 
				
			
			@ -552,7 +547,7 @@ error:
 | 
			
		|||
    this->input->buffers = NULL;
 | 
			
		||||
    this->input->n_buffers = 0;
 | 
			
		||||
    this->input->allocated = false;
 | 
			
		||||
    pinos_link_report_error (this, error);
 | 
			
		||||
    pinos_link_update_state (this, PINOS_LINK_STATE_ERROR, error);
 | 
			
		||||
    return res;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -565,9 +560,9 @@ do_start (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state)
 | 
			
		|||
  if (in_state < SPA_NODE_STATE_PAUSED || out_state < SPA_NODE_STATE_PAUSED)
 | 
			
		||||
    return SPA_RESULT_OK;
 | 
			
		||||
  else if (in_state == SPA_NODE_STATE_STREAMING && out_state == SPA_NODE_STATE_STREAMING) {
 | 
			
		||||
    pinos_link_update_state (this, PINOS_LINK_STATE_RUNNING);
 | 
			
		||||
    pinos_link_update_state (this, PINOS_LINK_STATE_RUNNING, NULL);
 | 
			
		||||
  } else {
 | 
			
		||||
    pinos_link_update_state (this, PINOS_LINK_STATE_PAUSED);
 | 
			
		||||
    pinos_link_update_state (this, PINOS_LINK_STATE_PAUSED, NULL);
 | 
			
		||||
 | 
			
		||||
    if (in_state == SPA_NODE_STATE_PAUSED) {
 | 
			
		||||
      res = pinos_node_set_state (this->input->node, PINOS_NODE_STATE_RUNNING);
 | 
			
		||||
| 
						 | 
				
			
			@ -587,9 +582,16 @@ check_states (PinosLink *this,
 | 
			
		|||
  SpaNodeState in_state, out_state;
 | 
			
		||||
 | 
			
		||||
again:
 | 
			
		||||
  if (this->state == PINOS_LINK_STATE_ERROR)
 | 
			
		||||
    return SPA_RESULT_ERROR;
 | 
			
		||||
 | 
			
		||||
  if (this->input == NULL || this->output == NULL)
 | 
			
		||||
    return SPA_RESULT_OK;
 | 
			
		||||
 | 
			
		||||
  if (this->input->node->state == PINOS_NODE_STATE_ERROR ||
 | 
			
		||||
      this->output->node->state == PINOS_NODE_STATE_ERROR)
 | 
			
		||||
    return SPA_RESULT_ERROR;
 | 
			
		||||
 | 
			
		||||
  in_state = this->input->node->node->state;
 | 
			
		||||
  out_state = this->output->node->node->state;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -652,7 +654,7 @@ on_port_unlinked (PinosPort *port, PinosLink *this, SpaResult res, uint32_t id)
 | 
			
		|||
  pinos_signal_emit (&this->core->port_unlinked, this, port);
 | 
			
		||||
 | 
			
		||||
  if (this->input == NULL || this->output == NULL) {
 | 
			
		||||
    pinos_link_update_state (this, PINOS_LINK_STATE_UNLINKED);
 | 
			
		||||
    pinos_link_update_state (this, PINOS_LINK_STATE_UNLINKED, NULL);
 | 
			
		||||
    pinos_link_destroy (this);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -719,7 +721,11 @@ bool
 | 
			
		|||
pinos_link_activate (PinosLink *this)
 | 
			
		||||
{
 | 
			
		||||
  spa_ringbuffer_init (&this->ringbuffer, SPA_N_ELEMENTS (this->queue));
 | 
			
		||||
  check_states (this, NULL, SPA_RESULT_OK);
 | 
			
		||||
  pinos_main_loop_defer (this->core->main_loop,
 | 
			
		||||
                         this,
 | 
			
		||||
                         SPA_RESULT_WAIT_SYNC,
 | 
			
		||||
                         (PinosDeferFunc) check_states,
 | 
			
		||||
                         this);
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -766,6 +772,8 @@ link_bind_func (PinosGlobal *global,
 | 
			
		|||
                                 global->core->uri.link,
 | 
			
		||||
                                 global->object,
 | 
			
		||||
                                 link_unbind_func);
 | 
			
		||||
  if (resource == NULL)
 | 
			
		||||
    goto no_mem;
 | 
			
		||||
 | 
			
		||||
  resource->dispatch_func = link_dispatch_func;
 | 
			
		||||
  resource->dispatch_data = global;
 | 
			
		||||
| 
						 | 
				
			
			@ -785,6 +793,12 @@ link_bind_func (PinosGlobal *global,
 | 
			
		|||
                               PINOS_MESSAGE_LINK_INFO,
 | 
			
		||||
                               &m,
 | 
			
		||||
                               true);
 | 
			
		||||
  return;
 | 
			
		||||
 | 
			
		||||
no_mem:
 | 
			
		||||
  pinos_resource_send_error (client->core_resource,
 | 
			
		||||
                             SPA_RESULT_NO_MEMORY,
 | 
			
		||||
                             "no memory");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PinosLink *
 | 
			
		||||
| 
						 | 
				
			
			@ -798,6 +812,9 @@ pinos_link_new (PinosCore       *core,
 | 
			
		|||
  PinosLink *this;
 | 
			
		||||
 | 
			
		||||
  impl = calloc (1, sizeof (PinosLinkImpl));
 | 
			
		||||
  if (impl == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  this = &impl->this;
 | 
			
		||||
  pinos_log_debug ("link %p: new", this);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -97,6 +97,8 @@ main_loop_defer (PinosMainLoop  *loop,
 | 
			
		|||
    spa_list_remove (&item->link);
 | 
			
		||||
  } else {
 | 
			
		||||
    item = malloc (sizeof (WorkItem));
 | 
			
		||||
    if (item == NULL)
 | 
			
		||||
      return SPA_ID_INVALID;
 | 
			
		||||
  }
 | 
			
		||||
  item->id = ++impl->counter;
 | 
			
		||||
  item->obj = obj;
 | 
			
		||||
| 
						 | 
				
			
			@ -189,10 +191,15 @@ pinos_main_loop_new (void)
 | 
			
		|||
  PinosMainLoop *this;
 | 
			
		||||
 | 
			
		||||
  impl = calloc (1, sizeof (PinosMainLoopImpl));
 | 
			
		||||
  if (impl == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  pinos_log_debug ("main-loop %p: new", impl);
 | 
			
		||||
  this = &impl->this;
 | 
			
		||||
 | 
			
		||||
  this->loop = pinos_loop_new ();
 | 
			
		||||
  if (this->loop == NULL)
 | 
			
		||||
    goto no_loop;
 | 
			
		||||
 | 
			
		||||
  pinos_signal_init (&this->destroy_signal);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -208,6 +215,10 @@ pinos_main_loop_new (void)
 | 
			
		|||
  spa_list_init (&impl->free_list);
 | 
			
		||||
 | 
			
		||||
  return this;
 | 
			
		||||
 | 
			
		||||
no_loop:
 | 
			
		||||
  free (impl);
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -123,6 +123,8 @@ module_bind_func (PinosGlobal *global,
 | 
			
		|||
                                 global->core->uri.module,
 | 
			
		||||
                                 global->object,
 | 
			
		||||
                                 NULL);
 | 
			
		||||
  if (resource == NULL)
 | 
			
		||||
    goto no_mem;
 | 
			
		||||
 | 
			
		||||
  resource->dispatch_func = module_dispatch_func;
 | 
			
		||||
  resource->dispatch_data = global;
 | 
			
		||||
| 
						 | 
				
			
			@ -141,6 +143,12 @@ module_bind_func (PinosGlobal *global,
 | 
			
		|||
                               PINOS_MESSAGE_MODULE_INFO,
 | 
			
		||||
                               &m,
 | 
			
		||||
                               true);
 | 
			
		||||
  return;
 | 
			
		||||
 | 
			
		||||
no_mem:
 | 
			
		||||
  pinos_resource_send_error (resource,
 | 
			
		||||
                             SPA_RESULT_NO_MEMORY,
 | 
			
		||||
                             "no memory");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -201,6 +209,9 @@ pinos_module_load (PinosCore    *core,
 | 
			
		|||
    goto no_pinos_module;
 | 
			
		||||
 | 
			
		||||
  impl = calloc (1, sizeof (PinosModuleImpl));
 | 
			
		||||
  if (impl == NULL)
 | 
			
		||||
    goto no_mem;
 | 
			
		||||
 | 
			
		||||
  impl->hnd = hnd;
 | 
			
		||||
 | 
			
		||||
  this = &impl->this;
 | 
			
		||||
| 
						 | 
				
			
			@ -229,10 +240,11 @@ not_found:
 | 
			
		|||
  }
 | 
			
		||||
open_failed:
 | 
			
		||||
  {
 | 
			
		||||
    asprintf (err, "Failed to open module: %s", dlerror ());
 | 
			
		||||
    asprintf (err, "Failed to open module: \"%s\" %s", filename, dlerror ());
 | 
			
		||||
    free (filename);
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
no_mem:
 | 
			
		||||
no_pinos_module:
 | 
			
		||||
  {
 | 
			
		||||
    asprintf (err, "\"%s\" is not a pinos module", name);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -422,6 +422,8 @@ node_bind_func (PinosGlobal *global,
 | 
			
		|||
                                 global->core->uri.registry,
 | 
			
		||||
                                 global->object,
 | 
			
		||||
                                 node_unbind_func);
 | 
			
		||||
  if (resource == NULL)
 | 
			
		||||
    goto no_mem;
 | 
			
		||||
 | 
			
		||||
  resource->dispatch_func = node_dispatch_func;
 | 
			
		||||
  resource->dispatch_data = global;
 | 
			
		||||
| 
						 | 
				
			
			@ -435,12 +437,19 @@ node_bind_func (PinosGlobal *global,
 | 
			
		|||
  info.change_mask = ~0;
 | 
			
		||||
  info.name = this->name;
 | 
			
		||||
  info.state = this->state;
 | 
			
		||||
  info.error = this->error;
 | 
			
		||||
  info.props = this->properties ? &this->properties->dict : NULL;
 | 
			
		||||
 | 
			
		||||
  pinos_resource_send_message (resource,
 | 
			
		||||
                               PINOS_MESSAGE_NODE_INFO,
 | 
			
		||||
                               &m,
 | 
			
		||||
                               true);
 | 
			
		||||
  return;
 | 
			
		||||
 | 
			
		||||
no_mem:
 | 
			
		||||
  pinos_resource_send_error (resource,
 | 
			
		||||
                             SPA_RESULT_NO_MEMORY,
 | 
			
		||||
                             "no memory");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
| 
						 | 
				
			
			@ -482,6 +491,9 @@ pinos_node_new (PinosCore       *core,
 | 
			
		|||
  PinosNode *this;
 | 
			
		||||
 | 
			
		||||
  impl = calloc (1, sizeof (PinosNodeImpl));
 | 
			
		||||
  if (impl == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  this = &impl->this;
 | 
			
		||||
  this->core = core;
 | 
			
		||||
  pinos_log_debug ("node %p: new", this);
 | 
			
		||||
| 
						 | 
				
			
			@ -514,6 +526,9 @@ pinos_node_new (PinosCore       *core,
 | 
			
		|||
    if (this->properties == NULL)
 | 
			
		||||
      this->properties = pinos_properties_new (NULL, NULL);
 | 
			
		||||
 | 
			
		||||
    if (this->properties)
 | 
			
		||||
      goto no_mem;
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < this->node->info->n_items; i++)
 | 
			
		||||
      pinos_properties_set (this->properties,
 | 
			
		||||
                            this->node->info->items[i].key,
 | 
			
		||||
| 
						 | 
				
			
			@ -532,6 +547,11 @@ pinos_node_new (PinosCore       *core,
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  return this;
 | 
			
		||||
 | 
			
		||||
no_mem:
 | 
			
		||||
  free (this->name);
 | 
			
		||||
  free (impl);
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static SpaResult
 | 
			
		||||
| 
						 | 
				
			
			@ -814,6 +834,7 @@ pinos_node_update_state (PinosNode      *node,
 | 
			
		|||
    m.info = &info;
 | 
			
		||||
    info.change_mask = 1 << 1;
 | 
			
		||||
    info.state = node->state;
 | 
			
		||||
    info.error = node->error;
 | 
			
		||||
 | 
			
		||||
    spa_list_for_each (resource, &node->resource_list, link) {
 | 
			
		||||
      info.id = node->global->id;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,6 +41,9 @@ pinos_port_new (PinosNode      *node,
 | 
			
		|||
  PinosPort *this;
 | 
			
		||||
 | 
			
		||||
  impl = calloc (1, sizeof (PinosPortImpl));
 | 
			
		||||
  if (impl == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  this = &impl->this;
 | 
			
		||||
  this->node = node;
 | 
			
		||||
  this->direction = direction;
 | 
			
		||||
| 
						 | 
				
			
			@ -177,6 +180,8 @@ pinos_port_link (PinosPort       *output_port,
 | 
			
		|||
                           input_port,
 | 
			
		||||
                           format_filter,
 | 
			
		||||
                           properties);
 | 
			
		||||
    if (link == NULL)
 | 
			
		||||
      goto no_mem;
 | 
			
		||||
 | 
			
		||||
    spa_list_insert (output_port->links.prev, &link->output_link);
 | 
			
		||||
    spa_list_insert (input_port->links.prev, &link->input_link);
 | 
			
		||||
| 
						 | 
				
			
			@ -209,6 +214,8 @@ was_linked:
 | 
			
		|||
    asprintf (error, "input port was already linked");
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
no_mem:
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static SpaResult
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,6 +31,9 @@ pinos_resource_new (PinosClient *client,
 | 
			
		|||
  PinosResource *this;
 | 
			
		||||
 | 
			
		||||
  this = calloc (1, sizeof (PinosResource));
 | 
			
		||||
  if (this == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  this->core = client->core;
 | 
			
		||||
  this->client = client;
 | 
			
		||||
  this->id = id;
 | 
			
		||||
| 
						 | 
				
			
			@ -95,15 +98,42 @@ pinos_resource_send_message (PinosResource     *resource,
 | 
			
		|||
                             void              *message,
 | 
			
		||||
                             bool               flush)
 | 
			
		||||
{
 | 
			
		||||
  if (resource->send_func)
 | 
			
		||||
    return resource->send_func (resource,
 | 
			
		||||
                                resource->id,
 | 
			
		||||
                                opcode,
 | 
			
		||||
                                message,
 | 
			
		||||
                                flush,
 | 
			
		||||
                                resource->send_data);
 | 
			
		||||
  if (!resource->send_func) {
 | 
			
		||||
    pinos_log_error ("resource %p: send func not implemented", resource);
 | 
			
		||||
    return SPA_RESULT_NOT_IMPLEMENTED;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  pinos_log_error ("resource %p: send func not implemented", resource);
 | 
			
		||||
 | 
			
		||||
  return SPA_RESULT_NOT_IMPLEMENTED;
 | 
			
		||||
  return resource->send_func (resource,
 | 
			
		||||
                              resource->id,
 | 
			
		||||
                              opcode,
 | 
			
		||||
                              message,
 | 
			
		||||
                              flush,
 | 
			
		||||
                              resource->send_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SpaResult
 | 
			
		||||
pinos_resource_send_error (PinosResource     *resource,
 | 
			
		||||
                           SpaResult          res,
 | 
			
		||||
                           const char        *message,
 | 
			
		||||
                           ...)
 | 
			
		||||
{
 | 
			
		||||
  PinosClient *client = resource->client;
 | 
			
		||||
  PinosMessageError m;
 | 
			
		||||
  char buffer[128];
 | 
			
		||||
  va_list ap;
 | 
			
		||||
 | 
			
		||||
  va_start (ap, message);
 | 
			
		||||
  vsnprintf (buffer, sizeof (buffer), message, ap);
 | 
			
		||||
  va_end (ap);
 | 
			
		||||
 | 
			
		||||
  m.id = resource->id;
 | 
			
		||||
  m.res = res;
 | 
			
		||||
  m.error = buffer;
 | 
			
		||||
 | 
			
		||||
  pinos_log_error ("resource %p: %u send error %d %s", resource, resource->id, res, buffer);
 | 
			
		||||
 | 
			
		||||
  return pinos_resource_send_message (client->core_resource,
 | 
			
		||||
                                      PINOS_MESSAGE_ERROR,
 | 
			
		||||
                                      &m,
 | 
			
		||||
                                      true);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -76,6 +76,9 @@ SpaResult       pinos_resource_send_message       (PinosResource     *resource,
 | 
			
		|||
                                                   uint32_t           opcode,
 | 
			
		||||
                                                   void              *message,
 | 
			
		||||
                                                   bool               flush);
 | 
			
		||||
SpaResult       pinos_resource_send_error         (PinosResource     *resource,
 | 
			
		||||
                                                   SpaResult          res,
 | 
			
		||||
                                                   const char        *message, ...);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,6 +28,7 @@ typedef struct {
 | 
			
		|||
  PinosContext *context;
 | 
			
		||||
 | 
			
		||||
  PinosListener on_state_changed;
 | 
			
		||||
  PinosListener on_subscription;
 | 
			
		||||
} Data;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
| 
						 | 
				
			
			@ -110,7 +111,11 @@ dump_node_info (PinosContext        *c,
 | 
			
		|||
  printf ("\ttype: %s\n", PINOS_NODE_URI);
 | 
			
		||||
  if (data->print_all) {
 | 
			
		||||
    printf ("%c\tname: \"%s\"\n", MARK_CHANGE (0), info->name);
 | 
			
		||||
    printf ("%c\tstate: \"%s\"\n", MARK_CHANGE (1), pinos_node_state_as_string (info->state));
 | 
			
		||||
    printf ("%c\tstate: \"%s\"", MARK_CHANGE (1), pinos_node_state_as_string (info->state));
 | 
			
		||||
    if (info->state == PINOS_NODE_STATE_ERROR && info->error)
 | 
			
		||||
      printf (" \"%s\"\n", info->error);
 | 
			
		||||
    else
 | 
			
		||||
      printf ("\n");
 | 
			
		||||
    print_properties (info->props, MARK_CHANGE (2));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -202,11 +207,11 @@ dump_object (PinosContext           *context,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
subscription_cb (PinosContext           *context,
 | 
			
		||||
on_subscription (PinosListener          *listener,
 | 
			
		||||
                 PinosContext           *context,
 | 
			
		||||
                 PinosSubscriptionEvent  event,
 | 
			
		||||
                 uint32_t                type,
 | 
			
		||||
                 uint32_t                id,
 | 
			
		||||
                 void                   *data)
 | 
			
		||||
                 uint32_t                id)
 | 
			
		||||
{
 | 
			
		||||
  DumpData dd;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -267,9 +272,9 @@ main (int argc, char *argv[])
 | 
			
		|||
                    &data.on_state_changed,
 | 
			
		||||
                    on_state_changed);
 | 
			
		||||
 | 
			
		||||
  pinos_context_subscribe (data.context,
 | 
			
		||||
                           subscription_cb,
 | 
			
		||||
                           &data);
 | 
			
		||||
  pinos_signal_add (&data.context->subscription,
 | 
			
		||||
                    &data.on_subscription,
 | 
			
		||||
                    on_subscription);
 | 
			
		||||
 | 
			
		||||
  pinos_context_connect (data.context);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -66,6 +66,7 @@ typedef enum {
 | 
			
		|||
  SPA_RESULT_WRONG_STATE               = -29,
 | 
			
		||||
  SPA_RESULT_ASYNC_BUSY                = -30,
 | 
			
		||||
  SPA_RESULT_INVALID_OBJECT_ID         = -31,
 | 
			
		||||
  SPA_RESULT_NO_MEMORY                 = -32,
 | 
			
		||||
} SpaResult;
 | 
			
		||||
 | 
			
		||||
#define SPA_ASYNC_MASK                  (3 << 30)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue