示例#1
0
/*

	closure: a GClosure
	return_value: a GValue to store the return value. May be NULL if the callback of closure doesn't return a value.
	n_param_values: the length of the param_values array
	param_values: an array of GValues holding the arguments on which to invoke the callback of closure
	invocation_hint: a context-dependent invocation hint
*/
void
g_closure_invoke (GClosure       *closure,
		  GValue /*out*/ *return_value,
		  guint           n_param_values,
		  const GValue   *param_values,
		  gpointer        invocation_hint)
{
	/*
	设置状态防止重入
	*/
	closure->ref_count += 1;
	closure->in_marshal = TRUE;

	// 得到marshal的指针
	if (closure->meta_marshal)
	{
	  	marshal_data = closure->notifiers[0].data;
	  	marshal = (GClosureMarshal) closure->notifiers[0].notify;
	}
	else
	{
	  	marshal_data = NULL;
	  	marshal = closure->marshal;
	}
	
	/*
	分别调用
		pre-notifer
		marshal
		post-notifier
	*/
	closure_invoke_notifiers (closure, PRE_NOTIFY);
	marshal (closure,
	       return_value,
	       n_param_values, param_values,
	       invocation_hint,
	       marshal_data);
	closure_invoke_notifiers (closure, POST_NOTIFY);
	
	// 恢复重入状态
	closure->in_marshal = in_marshal;  
	g_closure_unref (closure); 
}
示例#2
0
/**
 * g_closure_invoke:
 * @closure: a #GClosure
 * @return_value: a #GValue to store the return value. May be %NULL if the
 *                callback of @closure doesn't return a value.
 * @n_param_values: the length of the @param_values array
 * @param_values: (array length=n_param_values): an array of
 *                #GValue<!-- -->s holding the arguments on which to
 *                invoke the callback of @closure
 * @invocation_hint: a context-dependent invocation hint
 *
 * Invokes the closure, i.e. executes the callback represented by the @closure.
 */
void
g_closure_invoke (GClosure       *closure,
		  GValue /*out*/ *return_value,
		  guint           n_param_values,
		  const GValue   *param_values,
		  gpointer        invocation_hint)
{
  g_return_if_fail (closure != NULL);

  g_closure_ref (closure);      /* preserve floating flag */
  if (!closure->is_invalid)
    {
      GClosureMarshal marshal;
      gpointer marshal_data;
      gboolean in_marshal = closure->in_marshal;

      g_return_if_fail (closure->marshal || closure->meta_marshal);

      SET (closure, in_marshal, TRUE);
      if (closure->meta_marshal)
	{
	  marshal_data = closure->notifiers[0].data;
	  marshal = (GClosureMarshal) closure->notifiers[0].notify;
	}
      else
	{
	  marshal_data = NULL;
	  marshal = closure->marshal;
	}
      if (!in_marshal)
	closure_invoke_notifiers (closure, PRE_NOTIFY);
      marshal (closure,
	       return_value,
	       n_param_values, param_values,
	       invocation_hint,
	       marshal_data);
      if (!in_marshal)
	closure_invoke_notifiers (closure, POST_NOTIFY);
      SET (closure, in_marshal, in_marshal);
    }
  g_closure_unref (closure);
}
示例#3
0
void
g_closure_invalidate (GClosure *closure)
{
  g_return_if_fail (closure != NULL);

  if (!closure->is_invalid)
    {
      closure->ref_count += 1;	/* preserve floating flag */
      closure->is_invalid = TRUE;
      closure_invoke_notifiers (closure, INOTIFY);
      g_closure_unref (closure);
    }
}
示例#4
0
/**
 * g_closure_invalidate:
 * @closure: GClosure to invalidate
 *
 * Sets a flag on the closure to indicate that its calling
 * environment has become invalid, and thus causes any future
 * invocations of g_closure_invoke() on this @closure to be
 * ignored. Also, invalidation notifiers installed on the closure will
 * be called at this point. Note that unless you are holding a
 * reference to the closure yourself, the invalidation notifiers may
 * unref the closure and cause it to be destroyed, so if you need to
 * access the closure after calling g_closure_invalidate(), make sure
 * that you've previously called g_closure_ref().
 *
 * Note that g_closure_invalidate() will also be called when the
 * reference count of a closure drops to zero (unless it has already
 * been invalidated before).
 */
void
g_closure_invalidate (GClosure *closure)
{
  g_return_if_fail (closure != NULL);

  if (!closure->is_invalid)
    {
      gboolean was_invalid;
      g_closure_ref (closure);           /* preserve floating flag */
      SWAP (closure, is_invalid, TRUE, &was_invalid);
      /* invalidate only once */
      if (!was_invalid)
        closure_invoke_notifiers (closure, INOTIFY);
      g_closure_unref (closure);
    }
}
示例#5
0
void
g_closure_unref (GClosure *closure)
{
  g_return_if_fail (closure != NULL);
  g_return_if_fail (closure->ref_count > 0);

  if (closure->ref_count == 1)	/* last unref, invalidate first */
    g_closure_invalidate (closure);

  closure->ref_count -= 1;

  if (closure->ref_count == 0)
    {
      closure_invoke_notifiers (closure, FNOTIFY);
      g_free (closure->notifiers);
      g_free (closure);
    }
}
示例#6
0
/**
 * g_closure_unref:
 * @closure: #GClosure to decrement the reference count on
 *
 * Decrements the reference count of a closure after it was previously
 * incremented by the same caller. If no other callers are using the
 * closure, then the closure will be destroyed and freed.
 */
void
g_closure_unref (GClosure *closure)
{
  guint new_ref_count;

  g_return_if_fail (closure != NULL);
  g_return_if_fail (closure->ref_count > 0);

  if (closure->ref_count == 1)	/* last unref, invalidate first */
    g_closure_invalidate (closure);

  DEC_ASSIGN (closure, ref_count, &new_ref_count);

  if (new_ref_count == 0)
    {
      closure_invoke_notifiers (closure, FNOTIFY);
      g_free (closure->notifiers);
      g_free (closure);
    }
}