Пример #1
0
/**
 * g_cond_timed_wait:
 * @cond: a #GCond
 * @mutex: a #GMutex that is currently locked
 * @abs_time: a #GTimeVal, determining the final time
 *
 * Waits until this thread is woken up on @cond, but not longer than
 * until the time specified by @abs_time. The @mutex is unlocked before
 * falling asleep and locked again before resuming.
 *
 * If @abs_time is %NULL, g_cond_timed_wait() acts like g_cond_wait().
 *
 * This function can be used even if g_thread_init() has not yet been
 * called, and, in that case, will immediately return %TRUE.
 *
 * To easily calculate @abs_time a combination of g_get_current_time()
 * and g_time_val_add() can be used.
 *
 * Returns: %TRUE if @cond was signalled, or %FALSE on timeout
 *
 * Deprecated:2.32: Use g_cond_wait_until() instead.
 */
gboolean
g_cond_timed_wait (GCond    *cond,
                   GMutex   *mutex,
                   GTimeVal *abs_time)
{
  gint64 end_time;

  if (abs_time == NULL)
    {
      g_cond_wait (cond, mutex);
      return TRUE;
    }

  end_time = abs_time->tv_sec;
  end_time *= 1000000;
  end_time += abs_time->tv_usec;

#ifdef CLOCK_MONOTONIC
  /* would be nice if we had clock_rtoffset, but that didn't seem to
   * make it into the kernel yet...
   */
  end_time += g_get_monotonic_time () - g_get_real_time ();
#else
  /* if CLOCK_MONOTONIC is not defined then g_get_montonic_time() and
   * g_get_real_time() are returning the same clock, so don't bother...
   */
#endif

  return g_cond_wait_until (cond, mutex, end_time);
}
Пример #2
0
static gpointer idle_thread (gpointer data)
{
    HTTPServer *http_server = (HTTPServer *)data;
    ForeachFuncData func_data;
    GSList *wakeup_list = NULL;

    func_data.http_server = http_server;
    func_data.wakeup_list = &wakeup_list;
    for (;;) {
        g_mutex_lock (&(http_server->idle_queue_mutex));
        while (g_tree_nnodes (http_server->idle_queue) == 0) {
            g_cond_wait (&(http_server->idle_queue_cond), &(http_server->idle_queue_mutex));
        }
        func_data.wakeup_time = 0;
        g_tree_foreach (http_server->idle_queue, gtree_foreach_func, &func_data);
        if (wakeup_list != NULL) {
            g_slist_foreach (wakeup_list, gslist_foreach_func, http_server);
            g_slist_free (wakeup_list);
            wakeup_list = NULL;
        }
        if (func_data.wakeup_time != 0) {
            /* more than one idle request in the idle queue, wait until. */
            g_cond_wait_until (&(http_server->idle_queue_cond), &(http_server->idle_queue_mutex), func_data.wakeup_time);
        }
        g_mutex_unlock (&(http_server->idle_queue_mutex));
    }

    return NULL;
}
Пример #3
0
OMX_ERRORTYPE
gst_omx_buf_tab_wait_free (GstOmxBufTab * buftab)
{
  OMX_ERRORTYPE error;
  guint64 endtime;

  g_return_val_if_fail (buftab, OMX_ErrorBadParameter);

  error = OMX_ErrorNone;
  endtime = g_get_monotonic_time () + 5 * G_TIME_SPAN_SECOND;

  g_mutex_lock (&buftab->tabmutex);

  /* Wait until all the buffers have return to the mothership */
  while (buftab->tabused)
    if (!g_cond_wait_until (&buftab->tabcond, &buftab->tabmutex, endtime))
      goto timeout;

  g_mutex_unlock (&buftab->tabmutex);

  return error;

timeout:
  g_print ("Failed %p, tabused %d\n", buftab, buftab->tabused);
  g_mutex_unlock (&buftab->tabmutex);
  error = OMX_ErrorTimeout;
  return error;
}
Пример #4
0
static gpointer
g_async_queue_pop_intern_unlocked (GAsyncQueue *queue,
                                   gboolean     wait,
                                   gint64       end_time)
{
  gpointer retval;

  if (!g_queue_peek_tail_link (&queue->queue) && wait)
    {
      queue->waiting_threads++;
      while (!g_queue_peek_tail_link (&queue->queue))
        {
	  if (end_time == -1)
	    g_cond_wait (&queue->cond, &queue->mutex);
	  else
	    {
	      if (!g_cond_wait_until (&queue->cond, &queue->mutex, end_time))
		break;
	    }
        }
      queue->waiting_threads--;
    }

  retval = g_queue_pop_tail (&queue->queue);

  g_assert (retval || !wait || end_time > 0);

  return retval;
}
OMX_BUFFERHEADERTYPE *
gst_omx_buf_queue_pop_buffer (GstOmxBufQueue * bufqueue)
{
  OMX_BUFFERHEADERTYPE *buffer = NULL;
  guint64 endtime;
  endtime = g_get_monotonic_time () + 5 * G_TIME_SPAN_SECOND;

  g_mutex_lock (&bufqueue->queuemutex);
retry:

  while (g_queue_is_empty (bufqueue->queue)) {
    if (!g_cond_wait_until (&bufqueue->queuecond, &bufqueue->queuemutex,
            endtime))
      goto timeout;
    else
      goto retry;
  }

  buffer = (OMX_BUFFERHEADERTYPE *) g_queue_pop_head (bufqueue->queue);

  g_mutex_unlock (&bufqueue->queuemutex);

  return buffer;

timeout:
  g_mutex_unlock (&bufqueue->queuemutex);
  return buffer;

}
Пример #6
0
/**
 * gst_clock_wait_for_sync:
 * @clock: a GstClock
 * @timeout: timeout for waiting or %GST_CLOCK_TIME_NONE
 *
 * Waits until @clock is synced for reporting the current time. If @timeout
 * is %GST_CLOCK_TIME_NONE it will wait forever, otherwise it will time out
 * after @timeout nanoseconds.
 *
 * For asynchronous waiting, the GstClock::synced signal can be used.
 *
 *
 * This returns immediately with TRUE if GST_CLOCK_FLAG_NEEDS_STARTUP_SYNC
 * is not set on the clock, or if the clock is already synced.
 *
 * Returns: %TRUE if waiting was successful, or %FALSE on timeout
 *
 * Since: 1.6
 */
gboolean
gst_clock_wait_for_sync (GstClock * clock, GstClockTime timeout)
{
  gboolean timed_out = FALSE;

  g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE);

  GST_OBJECT_LOCK (clock);
  if (!GST_OBJECT_FLAG_IS_SET (clock, GST_CLOCK_FLAG_NEEDS_STARTUP_SYNC)
      || clock->priv->synced) {
    GST_OBJECT_UNLOCK (clock);
    return TRUE;
  }

  if (timeout != GST_CLOCK_TIME_NONE) {
    gint64 end_time = g_get_monotonic_time () + gst_util_uint64_scale (timeout,
        G_TIME_SPAN_SECOND, GST_SECOND);

    while (!clock->priv->synced && !timed_out) {
      timed_out =
          !g_cond_wait_until (&clock->priv->sync_cond,
          GST_OBJECT_GET_LOCK (clock), end_time);
    }
  } else {
    timed_out = FALSE;
    while (!clock->priv->synced) {
      g_cond_wait (&clock->priv->sync_cond, GST_OBJECT_GET_LOCK (clock));
    }
  }
  GST_OBJECT_UNLOCK (clock);

  return !timed_out;
}
static gpointer connection_timeout_thread_func(ErDtlsConnection *self)
{
    ErDtlsConnectionPrivate *priv = self->priv;
    struct timeval timeout;
    gint64 end_time, wait_time;
    gint ret;

    while (priv->is_alive) {
        LOG_TRACE(self, "locking @ timeout");
        g_mutex_lock(&priv->mutex);
        LOG_TRACE(self, "locked @ timeout");

        if (DTLSv1_get_timeout(priv->ssl, &timeout)) {
            wait_time = timeout.tv_sec * G_USEC_PER_SEC + timeout.tv_usec;

            if (wait_time) {
                LOG_DEBUG(self, "waiting for %" G_GINT64_FORMAT " usec", wait_time);

                end_time = g_get_monotonic_time() + wait_time;

                LOG_TRACE(self, "wait @ timeout");
                g_cond_wait_until(&priv->condition, &priv->mutex, end_time);
                LOG_TRACE(self, "continued @ timeout");
            }

            ret = DTLSv1_handle_timeout(priv->ssl);

            LOG_DEBUG(self, "handle timeout returned %d, is_alive: %d", ret, priv->is_alive);

            if (ret < 0) {
                LOG_TRACE(self, "unlocking @ timeout failed");
                g_mutex_unlock(&priv->mutex);
                break; /* self failed after DTLS1_TMO_ALERT_COUNT (12) attempts */
            }

            if (ret > 0) {
                log_state(self, "handling timeout before poll");
                openssl_poll(self);
                log_state(self, "handling timeout after poll");
            }
        } else {
            LOG_DEBUG(self, "waiting indefinitely");

            priv->timeout_set = FALSE;

            while (!priv->timeout_set && priv->is_alive) {
                LOG_TRACE(self, "wait @ timeout");
                g_cond_wait(&priv->condition, &priv->mutex);
            }
            LOG_TRACE(self, "continued @ timeout");
        }

        LOG_TRACE(self, "unlocking @ timeout");
        g_mutex_unlock(&priv->mutex);
    }

    log_state(self, "timeout thread exiting");

    return NULL;
}
static void
fetch_items(GTask* task, gpointer source, gpointer task_data, GCancellable* cancel)
{
    g_assert(GT_IS_SEARCH_GAME_CONTAINER(source));

    GtSearchGameContainer* self = GT_SEARCH_GAME_CONTAINER(source);
    GtSearchGameContainerPrivate* priv = gt_search_game_container_get_instance_private(self);

    g_assert(G_IS_CANCELLABLE(cancel));
    g_assert(G_IS_TASK(task));

    if (g_task_return_error_if_cancelled(task))
        return;

    if (utils_str_empty(priv->query))
    {
        g_task_return_pointer(task, NULL, NULL);
        return;
    }

    g_assert_nonnull(task_data);

    FetchItemsData* data = task_data;

    g_mutex_lock(&priv->mutex);

    gint64 end_time = g_get_monotonic_time() + SEARCH_DELAY;

    g_cancellable_connect(cancel, G_CALLBACK(cancelled_cb), self, NULL);

    while (!g_cancellable_is_cancelled(cancel))
    {
        if (!g_cond_wait_until(&priv->cond, &priv->mutex, end_time))
        {
            /* We weren't cancelled */

            g_assert(!utils_str_empty(priv->query));

            GError* err = NULL;

            GList* items = data->offset == 0 ? gt_twitch_search_games(main_app->twitch,
                priv->query, data->amount, data->offset, &err) : NULL;

            if (err)
                g_task_return_error(task, err);
            else
                g_task_return_pointer(task, items, (GDestroyNotify) gt_game_list_free);

            g_mutex_unlock(&priv->mutex);

            return;
        }
    }

    /* We were cancelled */
    g_assert(g_task_return_error_if_cancelled(task));

    g_mutex_unlock(&priv->mutex);
}
Пример #9
0
static inline void
renderer_wait_until (App * app, GstClockTime pts)
{
  g_mutex_lock (&app->mutex);
  do {
  } while (g_cond_wait_until (&app->render_ready, &app->mutex, pts));
  g_mutex_unlock (&app->mutex);
}
Пример #10
0
gpointer display_thread(gpointer data)
{
    GCContext      *context             =  (GCContext*)data;
    GCConfig       *config              =  context->config;
    GCVDPAUContext *vdpau               = &context->VDPAU_context;
    Movie          *movie               =  context->movie_context;
    gint64          timeout             =  0;
    int             current_direction   =  DIRECTION_FORWARD;

    if (!context) 
        g_error("Missing context\n");

    movie->pre_load_surface  = vdpau->surface_queue.next;

    load_frame(context, movie->frame_offset, movie->pre_load_surface);
    
    do {
        movie->pre_load_surface = display_surface(context, movie->pre_load_surface);
        timeout = g_get_monotonic_time() + config->seconds_per_frame * G_TIME_SPAN_SECOND;

        g_mutex_lock(&movie->tick_lock);

        if (movie->ease_to) {
            movie->new_frame = FALSE;
            easeout_to_frame(context, movie->ease_to_frame, config->easing_factor);
            movie->ease_to = FALSE;
        }

        while (!movie->new_frame && !movie->ease_to && !context->exit) {
            if (!g_cond_wait_until(&movie->tick_cond, &movie->tick_lock, timeout)) {
                movie->frame_offset++;
                movie->fract_frame_count++;
                movie->play_direction = DIRECTION_FORWARD;
                movie->new_frame = TRUE;
                //g_message("tick: %lu", movie->frame_offset);
                break;
            }
        }

        movie->new_frame = FALSE;

        g_mutex_unlock(&movie->tick_lock);

        load_frame(context, movie->frame_offset, movie->pre_load_surface);
        
    } while (!context->exit);

    munmap(movie->planes, config->movie_size);
    close(movie->fd_movie);
    vdpau_exit(context);
    x11_exit(context);

    g_main_loop_quit(context->g_main_loop);

    return NULL;
}
Пример #11
0
static gboolean _cond_wait_until(GCond *cond, GMutex *mutex, gint64 end_time)
{
    gboolean ret = FALSE;
#ifdef HAVE_COND_INIT
    ret = g_cond_wait_until(cond, mutex, end_time);
#else
    GTimeVal time = { end_time / G_TIME_SPAN_SECOND,
                      end_time % G_TIME_SPAN_SECOND };
    ret = g_cond_timed_wait(cond, mutex, &time);
#endif
    return ret;
}
Пример #12
0
static void wait_for_rings_started(TestServer *s, size_t count)
{
    gint64 end_time;

    g_mutex_lock(&s->data_mutex);
    end_time = g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND;
    while (ctpop64(s->rings) != count) {
        if (!g_cond_wait_until(&s->data_cond, &s->data_mutex, end_time)) {
            /* timeout has passed */
            g_assert_cmpint(ctpop64(s->rings), ==, count);
            break;
        }
    }
Пример #13
0
/* Wait until cond is signalled, or timeout us have passed. 
 *
 * You can get spurious wakeups, use this in a loop.
 */
void 
vips_g_cond_timed_wait( GCond *cond, GMutex *mutex, gint64 timeout )
{
#ifdef HAVE_COND_INIT
	g_cond_wait_until( cond, mutex, 
		g_get_monotonic_time() + timeout );
#else
	GTimeVal time;

	g_get_current_time( &time );
	g_time_val_add( &time, timeout );
	g_cond_timed_wait( cond, mutex, &time );
#endif
}
Пример #14
0
static gpointer block_thread (gpointer data)
{
    HTTPServer *http_server = (HTTPServer *)data;
    gint64 wakeup_time;

    for (;;) {
        g_mutex_lock (&(http_server->block_queue_mutex));
        wakeup_time = g_get_monotonic_time () + G_TIME_SPAN_SECOND;
        g_cond_wait_until (&(http_server->block_queue_cond), &(http_server->block_queue_mutex), wakeup_time);
        g_queue_foreach (http_server->block_queue, block_queue_foreach_func, http_server);
        g_mutex_unlock (&(http_server->block_queue_mutex));
    }

    return NULL;
}
Пример #15
0
/* returns FALSE if cancelled, in which case the lock is not held */
gboolean
e_mapi_cancellable_rec_mutex_lock (EMapiCancellableRecMutex *rec_mutex,
				   GCancellable *cancellable,
				   GError **error)
{
	gulong handler_id;
	gboolean res = TRUE;

	g_return_val_if_fail (rec_mutex != NULL, FALSE);

	g_mutex_lock (&rec_mutex->cond_mutex);
	if (!cancellable) {
		g_mutex_unlock (&rec_mutex->cond_mutex);
		g_rec_mutex_lock (&rec_mutex->rec_mutex);
		return TRUE;
	}

	if (g_cancellable_is_cancelled (cancellable)) {
		if (error && !*error) {
			/* coverity[unchecked_value] */
			g_cancellable_set_error_if_cancelled (cancellable, error);
		}
		g_mutex_unlock (&rec_mutex->cond_mutex);
		return FALSE;
	}

	handler_id = g_signal_connect (cancellable, "cancelled",
		G_CALLBACK (cancellable_rec_mutex_cancelled_cb), rec_mutex);

	while (!g_rec_mutex_trylock (&rec_mutex->rec_mutex)) {
		/* recheck once per 10 seconds, just in case */
		g_cond_wait_until (&rec_mutex->cond, &rec_mutex->cond_mutex,
			g_get_monotonic_time () + (10 * G_TIME_SPAN_SECOND));

		if (g_cancellable_is_cancelled (cancellable)) {
			if (error && !*error)
				g_cancellable_set_error_if_cancelled (cancellable, error);
			res = FALSE;
			break;
		}
	}

	g_signal_handler_disconnect (cancellable, handler_id);

	g_mutex_unlock (&rec_mutex->cond_mutex);

	return res;
}
Пример #16
0
OMX_ERRORTYPE
gst_omx_buf_tab_get_free_buffer (GstOmxBufTab * buftab,
    OMX_BUFFERHEADERTYPE ** buffer)
{
  OMX_ERRORTYPE error;
  GList *table;
  GstOmxBufTabNode *node;
  guint64 endtime;

  g_return_val_if_fail (buftab, OMX_ErrorBadParameter);

  error = OMX_ErrorNone;
  table = buftab->table;
  endtime = g_get_monotonic_time () + 5 * G_TIME_SPAN_SECOND;

  *buffer = NULL;

  g_mutex_lock (&buftab->tabmutex);

retry:
  table = buftab->table;

  while (table) {
    node = (GstOmxBufTabNode *) table->data;
    if (!node->busy) {
      *buffer = node->buffer;
      break;
    }

    table = g_list_next (table);
  }

  while (!*buffer) {
    if (!g_cond_wait_until (&buftab->tabcond, &buftab->tabmutex, endtime))
      goto timeout;
    else
      goto retry;
  }

  g_mutex_unlock (&buftab->tabmutex);
  return error;

timeout:
  g_mutex_unlock (&buftab->tabmutex);
  error = OMX_ErrorTimeout;
  return error;

}
Пример #17
0
static void wait_for_log_fd(TestServer *s)
{
    gint64 end_time;

    g_mutex_lock(&s->data_mutex);
    end_time = g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND;
    while (s->log_fd == -1) {
        if (!g_cond_wait_until(&s->data_cond, &s->data_mutex, end_time)) {
            /* timeout has passed */
            g_assert(s->log_fd != -1);
            break;
        }
    }

    g_mutex_unlock(&s->data_mutex);
}
Пример #18
0
void delay_usec(unsigned int usec)
{
    GMutex mutex;
    GCond  cond;
    gint64 timeout;

    g_mutex_init(&mutex);
    g_cond_init(&cond);
    timeout = g_get_monotonic_time() + usec;
    g_mutex_lock(&mutex);

    while (g_cond_wait_until(&cond, &mutex, timeout)) ;

    g_mutex_unlock(&mutex);
    g_mutex_clear(&mutex);
    g_cond_clear(&cond);
}
Пример #19
0
OMX_ERRORTYPE
gst_omx_buf_tab_remove_buffer (GstOmxBufTab * buftab,
    OMX_BUFFERHEADERTYPE * buffer)
{
  OMX_ERRORTYPE error;
  GList *toremove;
  guint64 endtime;
  GstOmxBufTabNode *node;

  g_return_val_if_fail (buftab, OMX_ErrorBadParameter);
  g_return_val_if_fail (buffer, OMX_ErrorBadParameter);

  error = OMX_ErrorNone;
  toremove = NULL;

  g_mutex_lock (&buftab->tabmutex);

  endtime = g_get_monotonic_time () + 5 * G_TIME_SPAN_SECOND;

  toremove = g_list_find_custom (buftab->table, (gconstpointer) buffer,
      (GCompareFunc) gst_omx_buf_tab_compare);
  if (!toremove)
    goto notfound;
  node = (GstOmxBufTabNode *) toremove->data;

  while (node->busy)
    if (!g_cond_wait_until (&buftab->tabcond, &buftab->tabmutex, endtime))
      goto timeout;

  buftab->table = g_list_remove (buftab->table, (gpointer) toremove->data);
  g_free(node);
  g_mutex_unlock (&buftab->tabmutex);

  return error;

notfound:
  g_mutex_unlock (&buftab->tabmutex);
  error = OMX_ErrorResourcesLost;
  return error;

timeout:
  g_mutex_unlock (&buftab->tabmutex);
  error = OMX_ErrorTimeout;
  return error;
}
Пример #20
0
    bool Wait(uint32_t timeout_ms)
    {
      gint64 endTime;

      g_mutex_lock(&m_mutex);
      endTime = g_get_monotonic_time() + timeout_ms * G_TIME_SPAN_MILLISECOND;
      while (!m_isResolved)
      {
        if (!g_cond_wait_until(&m_cond, &m_mutex, endTime))
        {
          g_mutex_unlock(&m_mutex);
          return false;
        }
      }
      g_mutex_unlock(&m_mutex);

      return true;
    }
Пример #21
0
/**
 * e_cancellable_mutex_lock:
 * @mutex: an #ECancellableMutex instance
 * @cancellable: (allow-none): a #GCancellable, or %NULL
 *
 * Acquires lock on @mutex. The returned value indicates whether
 * the lock was acquired, while %FALSE is returned only either or
 * invalid arguments or the passed in @cancellable had been cancelled.
 * In case of %NULL @cancellable the function blocks like g_mutex_lock().
 *
 * Returns: %TRUE, if lock had been acquired, %FALSE otherwise
 *
 * Since: 3.8
 **/
gboolean
e_cancellable_mutex_lock (ECancellableMutex *mutex,
                          GCancellable *cancellable)
{
	gulong handler_id;
	gboolean res = TRUE;

	g_return_val_if_fail (mutex != NULL, FALSE);

	g_mutex_lock (&mutex->base.cond_mutex);
	if (!cancellable) {
		g_mutex_unlock (&mutex->base.cond_mutex);
		g_mutex_lock (&mutex->mutex);
		return TRUE;
	}

	if (g_cancellable_is_cancelled (cancellable)) {
		g_mutex_unlock (&mutex->base.cond_mutex);
		return FALSE;
	}

	handler_id = g_signal_connect (
		cancellable, "cancelled",
		G_CALLBACK (cancellable_locks_cancelled_cb), &mutex->base);

	while (!g_mutex_trylock (&mutex->mutex)) {
		/* recheck once per 10 seconds, just in case */
		g_cond_wait_until (
			&mutex->base.cond, &mutex->base.cond_mutex,
			g_get_monotonic_time () + (10 * G_TIME_SPAN_SECOND));

		if (g_cancellable_is_cancelled (cancellable)) {
			res = FALSE;
			break;
		}
	}

	g_signal_handler_disconnect (cancellable, handler_id);

	g_mutex_unlock (&mutex->base.cond_mutex);

	return res;
}
Пример #22
0
static gboolean
idle_start_test1_thread (gpointer use_thread_context)
{
	guint64 time;
	GThread *thread;

	g_mutex_lock (&test1_mutex);
	thread = g_thread_new ("test1_thread", test1_thread, use_thread_context);

	time = g_get_monotonic_time () + 5000000;
	if (g_cond_wait_until (&test1_cond, &test1_mutex, time))
		g_thread_join (thread);
	else {
		soup_test_assert (FALSE, "timeout");
		g_thread_unref (thread);
	}

	g_mutex_unlock (&test1_mutex);
	g_main_loop_quit (test1_loop);
	return FALSE;
}
Пример #23
0
static void wait_for_fds(TestServer *s)
{
    gint64 end_time;

    g_mutex_lock(&s->data_mutex);

    end_time = g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND;
    while (!s->fds_num) {
        if (!g_cond_wait_until(&s->data_cond, &s->data_mutex, end_time)) {
            /* timeout has passed */
            g_assert(s->fds_num);
            break;
        }
    }

    /* check for sanity */
    g_assert_cmpint(s->fds_num, >, 0);
    g_assert_cmpint(s->fds_num, ==, s->memory.nregions);

    g_mutex_unlock(&s->data_mutex);
}
Пример #24
0
int fs_condition_wait_until(fs_condition *condition, fs_mutex *mutex,
        int64_t end_time) {
#if defined(USE_PTHREADS)
    struct timespec tv;
    tv.tv_sec = end_time / 1000000;
    tv.tv_nsec = (end_time % 1000000) * 1000;
    return pthread_cond_timedwait(&condition->condition, &mutex->mutex, &tv);
#elif defined(USE_GLIB)
    // GTimeVal tv;
    // tv.tv_sec = end_time / 1000000;
    // tv.tv_usec = end_time % 1000000;
    // gboolean result = g_cond_timed_wait(
    //         &condition->condition, &mutex->mutex, &tv);
    gboolean result = g_cond_wait_until(
             &condition->condition, &mutex->mutex, end_time);
    return !result;
#elif defined(USE_SDL)
    // FIXME: no timed wait...
    return SDL_CondWait(condition->condition, mutex->mutex);
#else
#error no thread support
#endif
}
Пример #25
0
static void
WaitForManualEvent(ManualEvent ME)
{
#if GLIB_CHECK_VERSION (2,32,0)
    gint64 end_time;
#else
    GTimeVal tv;
#endif
    multi_debug("wait for manual event locks");
#if GLIB_CHECK_VERSION (2,32,0)
    g_mutex_lock(&condMutex);
    end_time = g_get_monotonic_time() + 10 * G_TIME_SPAN_SECOND;
#else
    g_mutex_lock(condMutex);
#endif
    while (!ME->signalled) {
        multi_debug("waiting for manual event");
#if GLIB_CHECK_VERSION (2,32,0)
        if (!g_cond_wait_until(&ME->cond, &condMutex, end_time))
#else
        g_get_current_time(&tv);
        g_time_val_add(&tv, 10 * 1000 * 1000);
        if (g_cond_timed_wait(ME->cond, condMutex, &tv))
#endif
            break;
        else {
            multi_debug("still waiting for manual event");
        }
    }

#if GLIB_CHECK_VERSION (2,32,0)
    g_mutex_unlock(&condMutex);
#else
    g_mutex_unlock(condMutex);
#endif
    multi_debug("wait for manual event unlocks");
}
Пример #26
0
/*!
 \brief Disables the serial connection and shuts down the reader thread
  */
G_MODULE_EXPORT void libreems_serial_disable(void)
{
	GIOChannel *channel = NULL;
	GAsyncQueue *queue = NULL;
	Serial_Params *serial_params = NULL;
	GMutex mutex;
	GCond *cond = NULL;
	GThread *thread = NULL;
	gboolean res = FALSE;
	gint tmpi = 0;

	ENTER();
	g_mutex_init(&mutex);
	DATA_SET(global_data,"serial_abort",GINT_TO_POINTER(TRUE));
	thread = (GThread *)DATA_GET(global_data,"serial_thread_id");
	g_mutex_lock(&mutex);
	/* Wait up to 0.25 seconds for thread to exit */
	cond = (GCond *)DATA_GET(global_data,"serial_reader_cond");
	g_return_if_fail(cond);
	if ((cond) && (thread))
	{
		res = g_cond_wait_until(cond,&mutex,g_get_monotonic_time() + 250 * G_TIME_SPAN_MILLISECOND);
		g_thread_join(thread);
	}
	DATA_SET(global_data,"serial_thread_id",NULL);
	/*
	   if (res)
	   printf("condition signaled\n");
	   else
	   printf("cond timeout\n");
	 */
	g_mutex_unlock(&mutex);
	g_mutex_clear(&mutex);
	EXIT();
	return;
}
Пример #27
0
int main(int argc, char **argv)
{
  GThread *thread;
  gint64   end_time;

  gegl_init (&argc, &argv);

  thread = g_thread_new (NULL, test, NULL);

  end_time = g_get_monotonic_time () + TIMEOUT;

  g_mutex_lock (&mutex);

  while (! finished)
    {
      if (! g_cond_wait_until (&cond, &mutex, end_time))
        break;
    }

  g_mutex_unlock (&mutex);

  if (finished)
    {
      g_thread_join (thread);

      gegl_exit ();

      return SUCCESS;
    }
  else
    {
      g_print ("timeout expired. failing.\n");

      return FAILURE;
    }
}
Пример #28
0
static bool wait_for_fds(TestServer *s)
{
    gint64 end_time;
    bool got_region;
    int i;

    g_mutex_lock(&s->data_mutex);

    end_time = g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND;
    while (!s->fds_num) {
        if (!g_cond_wait_until(&s->data_cond, &s->data_mutex, end_time)) {
            /* timeout has passed */
            g_assert(s->fds_num);
            break;
        }
    }

    /* check for sanity */
    g_assert_cmpint(s->fds_num, >, 0);
    g_assert_cmpint(s->fds_num, ==, s->memory.nregions);

    g_mutex_unlock(&s->data_mutex);

    got_region = false;
    for (i = 0; i < s->memory.nregions; ++i) {
        VhostUserMemoryRegion *reg = &s->memory.regions[i];
        if (reg->guest_phys_addr == 0) {
            got_region = true;
            break;
        }
    }
    if (!got_region) {
        g_test_skip("No memory at address 0x0");
    }
    return got_region;
}
Пример #29
0
/** @brief RmMDSDevice worker thread
 **/
static void rm_mds_factory(RmMDSDevice *device, RmMDS *mds) {
    /* rm_mds_factory processes tasks from device->task_list.
     * After completing one pass of the device, returns self to the
     * mds->pool threadpool. */
    gint processed = 0;
    g_mutex_lock(&device->lock);
    {
        /* check for empty queues - if so then wait a little while before giving up */
        if(!device->sorted_tasks && !device->unsorted_tasks && device->ref_count > 0) {
            /* timed wait for signal from rm_mds_push_task_impl() */
            gint64 end_time = g_get_monotonic_time() + MDS_EMPTYQUEUE_SLEEP_US;
            g_cond_wait_until(&device->cond, &device->lock, end_time);
        }

        /* sort and merge task lists */
        if(device->unsorted_tasks) {
            if(mds->prioritiser) {
                device->sorted_tasks = g_slist_concat(
                                           g_slist_sort_with_data(device->unsorted_tasks,
                                                   (GCompareDataFunc)rm_mds_compare,
                                                   (RmMDSSortFunc)mds->prioritiser),
                                           device->sorted_tasks);
            } else {
                device->sorted_tasks =
                    g_slist_concat(device->unsorted_tasks, device->sorted_tasks);
            }
            device->unsorted_tasks = NULL;
        }
    }
    g_mutex_unlock(&device->lock);

    /* process tasks from device->sorted_tasks */
    RmMDSTask *task = NULL;
    while(processed < mds->pass_quota && (task = rm_util_slist_pop(&device->sorted_tasks, &device->lock))) {
        if(mds->func(task->task_data, mds->user_data)) {
            /* task succeeded; update counters */
            ++processed;
        }
        rm_mds_task_free(task);
    }

    if(rm_mds_device_ref(device, 0) > 0) {
        /* return self to pool for further processing */
        if(processed == 0) {
            /* stalled queue; chill for a bit */
            g_usleep(1000);
        }
        rm_util_thread_pool_push(mds->pool, device);
    } else if(g_atomic_int_dec_and_test(&device->threads)) {
        /* free self and signal to rm_mds_free() */
        g_mutex_lock(&mds->lock);
        {
            rm_log_debug_line("Freeing device %" LLU " (pointer %p)", (RmOff)device->disk,
                              device);
            g_hash_table_remove(mds->disks, GINT_TO_POINTER(device->disk));
            rm_mds_device_free(device);
            g_cond_signal(&mds->cond);
        }
        g_mutex_unlock(&mds->lock);
    }
}
Пример #30
0
static gpointer
decoder_thread (gpointer data)
{
  App *const app = data;
  GError *error = NULL;
  GstVaapiDecoderStatus status;
  GstVaapiSurfaceProxy *proxy;
  RenderFrame *rfp;
  GstBuffer *buffer;
  GstClockTime pts;
  gboolean got_surface, got_eos = FALSE;
  gint64 end_time;
  guint ofs;

  g_print ("Decoder thread started\n");

#define SEND_ERROR(...)                                                 \
    do {                                                                \
        error = g_error_new(APP_ERROR, APP_ERROR_DECODER, __VA_ARGS__); \
        goto send_error;                                                \
    } while (0)

  pts = g_get_monotonic_time ();
  ofs = 0;
  while (!app->decoder_thread_cancel) {
    if (G_UNLIKELY (ofs == app->file_size))
      buffer = NULL;
    else {
      const gsize size = MIN (4096, app->file_size - ofs);
      buffer = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
          app->file_data, app->file_size, ofs, size, NULL, NULL);
      if (!buffer)
        SEND_ERROR ("failed to allocate new buffer");
      ofs += size;
    }
    if (!gst_vaapi_decoder_put_buffer (app->decoder, buffer))
      SEND_ERROR ("failed to push buffer to decoder");
    gst_buffer_replace (&buffer, NULL);

  get_surface:
    status = gst_vaapi_decoder_get_surface (app->decoder, &proxy);
    switch (status) {
      case GST_VAAPI_DECODER_STATUS_SUCCESS:
        gst_vaapi_surface_proxy_set_destroy_notify (proxy,
            (GDestroyNotify) decoder_release, app);
        rfp = render_frame_new ();
        if (!rfp)
          SEND_ERROR ("failed to allocate render frame");
        rfp->proxy = proxy;
        rfp->pts = pts;
        rfp->duration = app->frame_duration;
        pts += app->frame_duration;
        g_async_queue_push (app->decoder_queue, rfp);
        break;
      case GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA:
        /* nothing to do, just continue to the next iteration */
        break;
      case GST_VAAPI_DECODER_STATUS_END_OF_STREAM:
        gst_vaapi_decoder_flush (app->decoder);
        if (got_eos)
          goto send_eos;
        got_eos = TRUE;
        break;
      case GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE:
        end_time = g_get_monotonic_time () + G_TIME_SPAN_SECOND;
        g_mutex_lock (&app->mutex);
        got_surface = g_cond_wait_until (&app->decoder_ready, &app->mutex,
            end_time);
        g_mutex_unlock (&app->mutex);
        if (got_surface)
          goto get_surface;
        SEND_ERROR ("failed to acquire a surface within one second");
        break;
      default:
        SEND_ERROR ("%s", get_decoder_status_string (status));
        break;
    }
  }
  return NULL;

#undef SEND_ERROR

send_eos:
  app_send_eos (app);
  return NULL;

send_error:
  app_send_error (app, error);
  return NULL;
}