示例#1
0
void swd::storage::process_next() {
	boost::unique_lock<boost::mutex> consumer_lock(consumer_mutex_);

	while (!stop_) {
		/* Wait for a new request in the queue. */
		while (1) {
			/* Do not wait if there are still elements in the queue. */
			{
				boost::unique_lock<boost::mutex> queue_lock(queue_mutex_);

				if (!queue_.empty()) {
					break;
				}
			}

			cond_.wait(consumer_lock);
		}

		/* Move oldest element of queue to request. */
		swd::request_ptr request;

		{
			boost::unique_lock<boost::mutex> queue_lock(queue_mutex_);

			request = queue_.front();
			queue_.pop();
		}

		/* Saving is the time-consuming part, do outside of mutex. */
		this->save(request);
	}
}
示例#2
0
/**************************************************************************
 *       event_async_loop (private) :
 *
 * Send queued events.
 **************************************************************************/
static void * event_async_loop(void * arg)
{
    libvlc_event_manager_t * p_em = arg;
    libvlc_event_listener_t listener;
    libvlc_event_t event;

    vlc_threadvar_set(queue(p_em)->is_asynch_dispatch_thread_var, p_em);

    queue_lock(p_em);
    while (true) {
        int has_listener = pop(p_em, &listener, &event);

        if (has_listener)
        {
            queue_unlock(p_em);
            listener.pf_callback(&event, listener.p_user_data); // This might edit the queue
            queue_lock(p_em);
        }
        else
        {
            queue(p_em)->is_idle = true;

            mutex_cleanup_push(&queue(p_em)->lock);
            vlc_cond_broadcast(&queue(p_em)->signal_idle); // We'll be idle
            vlc_cond_wait(&queue(p_em)->signal, &queue(p_em)->lock);
            vlc_cleanup_pop();

            queue(p_em)->is_idle = false;
        }
    }
    queue_unlock(p_em);
    return NULL;
}
示例#3
0
QueueEntry *AddQueueEntry(QueueEntry * qep, char *sqlmsg)
{
    QueueEntry *lp = qep;

    alog(LOG_DEBUG, "Adding Query %s", sqlmsg);

    if (qep != NULL) {
        while (qep && qep->link != NULL) {
            qep = qep->link;
        }
        queue_lock();
        qep->link = (QueueEntry *) malloc(sizeof(QueueEntry));
        qep = qep->link;
        qep->link = NULL;
        qep->msg = sstrdup(sqlmsg);
        queue_signal();
        queue_unlock(NULL);
        return lp;
    } else {
        queue_lock();
        qep = (QueueEntry *) malloc(sizeof(QueueEntry));
        qep->link = NULL;
        qep->msg = sstrdup(sqlmsg);
        queue_signal();
        queue_unlock(NULL);
        return qep;
    }
}
示例#4
0
void *thQueueRecv(void *obj)
{
	BGBGC_Queue *ctx;
	void *p;
	ctx=(BGBGC_Queue *)obj;

	if(ctx->orov==ctx->irov)
	{
#if 0
		if(ctx->ovf)
		{
			queue_lock();
			p=dycar(ctx->ovf);
			ctx->ovf=dycdr(ctx->ovf);
			queue_unlock();
			return(p);
		}
#endif

		while(ctx->orov==ctx->irov)thWaitPtr(obj);
	}

	queue_lock();
	p=(void *)(ctx->msg[ctx->irov]);
	ctx->irov=(ctx->irov+1)&63;
	queue_unlock();
	return(p);
}
示例#5
0
// Thread which will handle dequeing and re-enqueing based on the status
// and the flags for all ports in the output buffer
void *output_monitor_routine(void *arg) {
    packet_t in_pkt ;
    ip_address_t address ;
    int dest_port=0 ;
    int loop_count= 0 ;
    element_to_queue * element ;

    while(!die) {

        // Only care dequing if there are elements.
        if((output_buffer->size > 0)) {
            // This will indeed dequeue the packet, but we may
            // have to put it back if the port isn't ready.

            queue_lock(output_buffer) ;
            dequeue(output_buffer,&in_pkt) ;
            queue_unlock(output_buffer) ;

            // Fetch the IP & lookup destination port
            ip_address_copy(&(in_pkt.address),&address);
            dest_port = cam_lookup_address(&address) ;
            if((dest_port != -1) && (dest_port < 4)) {
                // Wait for the lock
                port_lock(&(out_port[dest_port])) ;
                // If the flag is busy from the last write, then
                // we have to put the packet back in the queue and just
                // have to wait until we get to it again.
                if(out_port[dest_port].flag) {
                    element = calloc(1,sizeof(element_to_queue)) ;
                    packet_copy(&in_pkt,&(element->packet));

                    queue_lock(output_buffer) ;
                    enqueue(element,output_buffer) ;
                    queue_unlock(output_buffer) ;

                    port_unlock(&(out_port[dest_port])) ;
                    continue ;
                }
                // Port ready to be written , so go ahead and write.
                packet_copy(&in_pkt,&(out_port[dest_port].packet));
                out_port[dest_port].flag = TRUE ;
                port_unlock(&(out_port[dest_port])) ;
            }
        }
        // Make sure it tried to at least deque 5 elements, before we
        // make it sleep.
        if(loop_count > LOOP_COUNT) {
            loop_count = 0 ;
            sleep() ;
        } else
            loop_count++ ;
    }
}
void ff_circular_queue_abort(struct ff_circular_queue *cq)
{
	queue_lock(cq);
	cq->abort = true;
	queue_signal(cq);
	queue_unlock(cq);
}
void ServiceServerLink::callFinished()
{
  CallInfoPtr saved_call;
  ServiceServerLinkPtr self;
  {
    boost::mutex::scoped_lock queue_lock(call_queue_mutex_);
    boost::mutex::scoped_lock finished_lock(current_call_->finished_mutex_);

    ROS_DEBUG_NAMED("superdebug", "Client to service [%s] call finished with success=[%s]", service_name_.c_str(), current_call_->success_ ? "true" : "false");

    current_call_->finished_ = true;
    current_call_->finished_condition_.notify_all();

    saved_call = current_call_;
    current_call_ = CallInfoPtr();

    // If the call queue is empty here, we may be deleted as soon as we release these locks, so keep a shared pointer to ourselves until we return
    // ugly
    // jfaust TODO there's got to be a better way
    self = shared_from_this();
  }

  saved_call = CallInfoPtr();

  processNextCall();
}
示例#8
0
/// "Do on main thread" support.
static void iothread_service_main_thread_requests(void) {
    ASSERT_IS_MAIN_THREAD();

    // Move the queue to a local variable.
    std::queue<main_thread_request_t *> request_queue;
    {
        scoped_lock queue_lock(s_main_thread_request_q_lock);
        request_queue.swap(s_main_thread_request_queue);
    }

    if (!request_queue.empty()) {
        // Perform each of the functions. Note we are NOT responsible for deleting these. They are
        // stack allocated in their respective threads!
        while (!request_queue.empty()) {
            main_thread_request_t *req = request_queue.front();
            request_queue.pop();
            req->func();
            req->done = true;
        }

        // Ok, we've handled everybody. Announce the good news, and allow ourselves to be unlocked.
        // Note we must do this while holding the lock. Otherwise we race with the waiting threads:
        //
        // 1. waiting thread checks for done, sees false
        // 2. main thread performs request, sets done to true, posts to condition
        // 3. waiting thread unlocks lock, waits on condition (forever)
        //
        // Because the waiting thread performs step 1 under the lock, if we take the lock, we avoid
        // posting before the waiting thread is waiting.
        scoped_lock broadcast_lock(s_main_thread_performer_lock);
        s_main_thread_performer_cond.notify_all();
    }
}
示例#9
0
int qos_enqueue(struct sk_buff *skb,
		struct  asf_qdisc *sch,
		u32 *tc_filter_res)
{
	struct net_queue *queue;

	queue = qos_classify(skb, sch, tc_filter_res);
	if (NULL == queue) {

		asf_debug("QUEUE FULL:  skb->queue_mapping %d\n",
						skb->queue_mapping);
		/* Free the SKB in calling function */
		ASFSkbFree(skb);
		return -1;
	}

	skb->next = NULL;

	queue_lock(&(queue->lock));
	if (!queue->head) {
		queue->head = skb;
		queue->tail = skb;
	} else {
		queue->tail->next = skb;
		queue->tail = skb;
	}
	queue->queue_size++;
	queue_unlock(&(queue->lock));

	return 0;
}
示例#10
0
/* "Do on main thread" support */
static void iothread_service_main_thread_requests(void)
{
    ASSERT_IS_MAIN_THREAD();

    // Move the queue to a local variable
    std::queue<MainThreadRequest_t *> request_queue;
    {
        scoped_lock queue_lock(s_main_thread_request_queue_lock);
        std::swap(request_queue, s_main_thread_request_queue);
    }

    if (! request_queue.empty())
    {
        // Perform each of the functions
        // Note we are NOT responsible for deleting these. They are stack allocated in their respective threads!
        while (! request_queue.empty())
        {
            MainThreadRequest_t *req = request_queue.front();
            request_queue.pop();
            req->handlerResult = req->handler(req->context);
            req->done = true;
        }

        /* Ok, we've handled everybody. Announce the good news, and allow ourselves to be unlocked. Note we must do this while holding the lock. Otherwise we race with the waiting threads:
         1. waiting thread checks for done, sees false
         2. main thread performs request, sets done to true, posts to condition
         3. waiting thread unlocks lock, waits on condition (forever)
         Because the waiting thread performs step 1 under the lock, if we take the lock, we avoid posting before the waiting thread is waiting.
        */
        scoped_lock broadcast_lock(s_main_thread_performer_lock);
        VOMIT_ON_FAILURE(pthread_cond_broadcast(&s_main_thread_performer_condition));
    }
}
示例#11
0
文件: parse.c 项目: dolfly/nmdb
/* Creates a new queue entry and puts it into the queue. Returns 1 if success,
 * 0 if memory error. */
static int put_in_queue_long(const struct req_info *req,
		uint32_t operation, int sync,
		const unsigned char *key, size_t ksize,
		const unsigned char *val, size_t vsize,
		const unsigned char *newval, size_t nvsize)
{
	struct queue_entry *e;

	e = make_queue_long_entry(req, operation, key, ksize, val, vsize,
			newval, nvsize);
	if (e == NULL) {
		return 0;
	}
	queue_lock(op_queue);
	queue_put(op_queue, e);
	queue_unlock(op_queue);

	if (sync) {
		/* Signal the DB thread it has work only if it's a
		 * synchronous operation, asynchronous don't mind
		 * waiting. It does have a measurable impact on
		 * performance (2083847usec vs 2804973usec for sets on
		 * "test2d 100000 10 10"). */
		queue_signal(op_queue);
	}

	return 1;
}
示例#12
0
void iothread_perform_on_main(void_function_t &&func) {
    if (is_main_thread()) {
        func();
        return;
    }

    // Make a new request. Note we are synchronous, so this can be stack allocated!
    main_thread_request_t req(std::move(func));

    // Append it. Do not delete the nested scope as it is crucial to the proper functioning of this
    // code by virtue of the lock management.
    {
        scoped_lock queue_lock(s_main_thread_request_q_lock);
        s_main_thread_request_queue.push(&req);
    }

    // Tell the pipe.
    const char wakeup_byte = IO_SERVICE_MAIN_THREAD_REQUEST_QUEUE;
    assert_with_errno(write_loop(s_write_pipe, &wakeup_byte, sizeof wakeup_byte) != -1);

    // Wait on the condition, until we're done.
    std::unique_lock<std::mutex> perform_lock(s_main_thread_performer_lock);
    while (!req.done) {
        // It would be nice to support checking for cancellation here, but the clients need a
        // deterministic way to clean up to avoid leaks
        s_main_thread_performer_cond.wait(perform_lock);
    }

    // Ok, the request must now be done.
    assert(req.done);
}
示例#13
0
void SynergyWorker::AddSynergyCell(SynergyCellPtr cell_ptr) {
  IncreaseWorkingSize();
  typedef boost::unique_lock<boost::mutex> UniqueLock;
  UniqueLock queue_lock(queue_mutex_);
  synergy_cell_queue_.push_back(cell_ptr);
  have_work_.notify_one();
}
示例#14
0
void SubscriptionQueue::clear()
{
  boost::recursive_mutex::scoped_lock cb_lock(callback_mutex_);
  boost::mutex::scoped_lock queue_lock(queue_mutex_);

  queue_.clear();
  queue_size_ = 0;
}
void ff_circular_queue_advance_read(struct ff_circular_queue *cq)
{
	cq->read_index = (cq->read_index + 1) % cq->capacity;
	queue_lock(cq);
	--cq->size;
	queue_signal(cq);
	queue_unlock(cq);
}
示例#16
0
void gw_prioqueue_add_producer(gw_prioqueue_t *queue)
{
    gw_assert(queue != NULL);

    queue_lock(queue);
    queue->producers++;
    queue_unlock(queue);
}
示例#17
0
文件: mevent.c 项目: bigml/mevent
static void* mevent_start_base_entry(void *arg)
{
    int rv;
    struct timespec ts;
    struct queue_entry *q;

    struct event_entry *e = (struct event_entry*)arg;
    int *mypos = _tls_get_mypos();
    *mypos = e->cur_thread;

    mtc_dbg("I'm %s %dnd thread", e->name, *mypos);

    for (;;) {
        /* Condition waits are specified with absolute timeouts, see
         * pthread_cond_timedwait()'s SUSv3 specification for more
         * information. We need to calculate it each time.
         * We sleep for 1 sec. There's no real need for it to be too
         * fast (it's only used so that stop detection doesn't take
         * long), but we don't want it to be too slow either. */
        mutil_utc_time(&ts);
        ts.tv_sec += 1;

        rv = 0;
        queue_lock(e->op_queue[*mypos]);
        while (queue_isempty(e->op_queue[*mypos]) && rv == 0) {
            rv = queue_timedwait(e->op_queue[*mypos], &ts);
        }

        if (rv != 0 && rv != ETIMEDOUT) {
            errlog("Error in queue_timedwait()");
            /* When the timedwait fails the lock is released, so
             * we need to properly annotate this case. */
            __release(e->op_queue[*mypos]->lock);
            continue;
        }

        q = queue_get(e->op_queue[*mypos]);
        queue_unlock(e->op_queue[*mypos]);

        if (q == NULL) {
            if (e->loop_should_stop) {
                break;
            } else {
                continue;
            }
        }

        mtc_dbg("%s %d process", e->name, *mypos);

        e->process_driver(e, q, *mypos);

        /* Free the entry that was allocated when tipc queued the
         * operation. This also frees it's components. */
        queue_entry_free(q);
    }

    return NULL;
}
示例#18
0
文件: lua-chan.c 项目: lqefn/lua-chan
static long queue_acquire(struct queue_t* q)
{
    long refs;
    queue_lock(q);
    refs = ++ q->refs;
    queue_unlock(q);
    TRACE("queue_acquire: %s, refs=%d\n", q->name, q->refs);
    return refs;
}
示例#19
0
int thQueueMsg(void *obj)
{
	BGBGC_Queue *ctx;
	int i;
	queue_lock();
	ctx=(BGBGC_Queue *)obj; i=(ctx->orov-ctx->irov)&63;
	queue_unlock();
	return(i);
}
示例#20
0
void InputQueue::push(InputEvent event)
{
    {
        std::lock_guard<std::mutex> queue_lock(_queue_mutex);
        std::lock_guard<std::mutex> block_lock(_block_mutex);
        _queue.push(event);
    }
    _block_var.notify_all();
}
void ff_circular_queue_wait_write(struct ff_circular_queue *cq)
{
	queue_lock(cq);

	while (cq->size >= cq->capacity && !cq->abort)
		queue_wait(cq);

	queue_unlock(cq);
}
void ff_circular_queue_advance_write(struct ff_circular_queue *cq, void *item)
{
	cq->slots[cq->write_index] = item;
	cq->write_index = (cq->write_index + 1) % cq->capacity;

	queue_lock(cq);
	++cq->size;
	queue_unlock(cq);
}
示例#23
0
void TaskPool::wait_work(Summary *stats)
{
	thread_scoped_lock num_lock(num_mutex);

	while(num != 0) {
		num_lock.unlock();

		thread_scoped_lock queue_lock(TaskScheduler::queue_mutex);

		/* find task from this pool. if we get a task from another pool,
		 * we can get into deadlock */
		TaskScheduler::Entry work_entry;
		bool found_entry = false;
		list<TaskScheduler::Entry>::iterator it;

		for(it = TaskScheduler::queue.begin(); it != TaskScheduler::queue.end(); it++) {
			TaskScheduler::Entry& entry = *it;

			if(entry.pool == this) {
				work_entry = entry;
				found_entry = true;
				TaskScheduler::queue.erase(it);
				break;
			}
		}

		queue_lock.unlock();

		/* if found task, do it, otherwise wait until other tasks are done */
		if(found_entry) {
			/* run task */
			work_entry.task->run(0);

			/* delete task */
			delete work_entry.task;

			/* notify pool task was done */
			num_decrease(1);
		}

		num_lock.lock();
		if(num == 0)
			break;

		if(!found_entry) {
			THREADING_DEBUG("num==%d, Waiting for condition in TaskPool::wait_work !found_entry\n", num);
			num_cond.wait(num_lock);
			THREADING_DEBUG("num==%d, condition wait done in TaskPool::wait_work !found_entry\n", num);
		}
	}

	if(stats != NULL) {
		stats->time_total = time_dt() - start_time;
		stats->num_tasks_handled = num_tasks_handled;
	}
}
示例#24
0
void gw_prioqueue_remove_producer(gw_prioqueue_t *queue)
{
    gw_assert(queue != NULL);

    queue_lock(queue);
    gw_assert(queue->producers > 0);
    queue->producers--;
    pthread_cond_broadcast(&queue->nonempty);
    queue_unlock(queue);
}
示例#25
0
void gw_prioqueue_foreach(gw_prioqueue_t *queue, void(*fn)(const void *, long))
{
    register long i;

    gw_assert(queue != NULL && fn != NULL);
    
    queue_lock(queue);
    for (i = 1; i < queue->len; i++)
        fn(queue->tab[i]->item, i - 1);
    queue_unlock(queue);
}
示例#26
0
static void
remote_lock(struct sockaddr_in *remote, struct lock_msg *msg)
{
	/* make sure remote knows we are alive */
	send_lockmsg(ALIVE, (pid_t)0, remote, 0);

	/* clear out pid as it is meaningless on this node */
	msg->pid = (pid_t)0;

	queue_lock(LOCK_WRITE, msg, (daemonaddr_t *)remote);
}
示例#27
0
long gw_prioqueue_producer_count(gw_prioqueue_t *queue)
{
    long ret;

    gw_assert(queue != NULL);
    
    queue_lock(queue);
    ret = queue->producers;
    queue_unlock(queue);
    
    return ret;
}
示例#28
0
文件: queue.c 项目: iven/mychat
/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  queue_pop
 *  Description:  Pop a node from the queue.
 * =====================================================================================
 */
    Queue_node *
queue_pop ( Queue *queue )
{
    if (queue == NULL || queue_empty(queue)) {
        return NULL;
    }
    queue_lock(queue);
    Queue_node *node = queue->tail;
    queue->tail = node->next;
    queue_unlock(queue);
    return node;
}       /* -----  end of function queue_pop  ----- */
示例#29
0
long gw_prioqueue_len(gw_prioqueue_t *queue)
{
    long len;

    if (queue == NULL)
        return 0;
     
    queue_lock(queue);
    len = queue->len - 1;
    queue_unlock(queue);
    
    return len;
}
示例#30
0
void *queue_thread_main(void *arg)
{
#ifdef USE_THREADS
    while (1) {
        deno_cleanup_push(queue_unlock, NULL);
        queue_lock();
        queue_wait();
        deno_cleanup_pop(1);

        while (1) {
            deno_cleanup_push(queue_unlock, NULL);
            queue_lock();
            deno_cleanup_pop(1);

            while (qp != NULL) {
                qp = ExecuteQueue(qp);
            }
            break;
        }
    }
#endif
    return NULL;
}