Ejemplo n.º 1
0
int condreltimedwait(pthread_cond_t *c, pthread_mutex_t *m,
		     const struct timespec *reltime)
{
	int ret;

#ifdef HAVE_PTHREAD_COND_RELTIMEDWAIT_NP
	ret = pthread_cond_reltimedwait_np(c, m, reltime);
#else
	struct timespec abstime;
	struct timespec now;

	clock_gettime(CLOCK_REALTIME, &now);

	if ((now.tv_nsec + reltime->tv_nsec) >= 1000000000) {
		now.tv_sec++;
		now.tv_nsec -= 1000000000;
	}

	abstime.tv_sec  = now.tv_sec  + reltime->tv_sec;
	abstime.tv_nsec = now.tv_nsec + reltime->tv_nsec;

	ret = pthread_cond_timedwait(c, m, &abstime);
#endif

	if ((ret != 0) || (ret != ETIMEDOUT))
		VERIFY(0);

	return ret;
}
//申请收货
//只有遍历所有生产者后才会锁.
TInt32 CProduerAndConsumer::RequireFetchProduct(TUInt32 timeout)
{
    
#ifdef _WIN32
    int ret = WaitForSingleObject(m_cond,timeout);
    if (WAIT_TIMEOUT == ret)
    {
        return TIME_OUT;
    }
    if (WAIT_OBJECT_0 == ret)
    {
        return SUCCESS;
    }
#else

    struct timeval tv;
    struct timezone tz;


    //if()
    {
        struct timespec ts;

        //unsigned long long endtime = ((long long)tv.tv_sec) * 1000000 + tv.tv_usec+1000*timeout;

        ts.tv_sec = endtime/1000000;
        ts.tv_nsec = (endtime%1000000)*1000;

        pthread_mutex_lock(&m_mutex);
        //在这段小时间内,生产者又生产东西了!
        if (m_productsNr)
        {
            int result = m_productsNr;
            m_productsNr = 0;
            pthread_mutex_unlock(&m_mutex);
            return result;
        }
        int retcode= pthread_cond_reltimedwait_np(&m_cond,&m_mutex,&ts);
        //if (m_productsNr)
        {
            int result = (int)m_productsNr;
            m_productsNr = 0;
            pthread_mutex_unlock(&m_mutex);
            return result;
        }
    }
#endif

    return SUCCESS;
}
Ejemplo n.º 3
0
/*
 * vs_eng_get
 * Get next available scan engine connection.
 * If retry == B_TRUE look for a scan engine with no errors.
 *
 * Returns: 0 - success
 *         -1 - error
 */
int
vs_eng_get(vs_eng_ctx_t *eng_ctx, boolean_t retry)
{
	struct timespec tswait;
	int eidx, cidx, sockfd;
	vs_engine_t *eng;
	vs_connection_t *cxn;

	(void) pthread_mutex_lock(&vs_eng_mutex);

	/*
	 * If no engines connections configured OR
	 * retry and only one engine configured, give up
	 */
	if ((vs_eng_total_maxcon <= 0) ||
	    ((retry == B_TRUE) && (vs_eng_count <= 1))) {
		(void) pthread_mutex_unlock(&vs_eng_mutex);
		return (-1);
	}

	tswait.tv_sec = vs_eng_wait;
	tswait.tv_nsec = 0;

	while ((vscand_get_state() != VS_STATE_SHUTDOWN) &&
	    (vs_eng_find_connection(&eidx, &cidx, retry) == -1)) {
		/* If retry and all configured engines have errors, give up */
		if (retry && vs_eng_check_errors() == B_TRUE) {
			(void) pthread_mutex_unlock(&vs_eng_mutex);
			return (-1);
		}

		/* wait for a connection to become available */
		vs_eng_wait_count++;
		if (pthread_cond_reltimedwait_np(&vs_eng_cv, &vs_eng_mutex,
		    &tswait) < 0) {
			syslog(LOG_NOTICE, "Scan Engine "
			    "- timeout waiting for available engine");
			vs_eng_wait_count--;
			(void) pthread_mutex_unlock(&vs_eng_mutex);
			return (-1);
		}
		vs_eng_wait_count--;
	}

	if (vscand_get_state() == VS_STATE_SHUTDOWN) {
		(void) pthread_mutex_unlock(&vs_eng_mutex);
		return (-1);
	}

	eng = &(vs_engines[eidx]);
	cxn = &(eng->vse_cxns[cidx]);

	/* update in use counts */
	eng->vse_inuse++;
	vs_eng_total_inuse++;

	/* update round-robin index */
	if (!retry)
		vs_eng_next = (eidx == VS_SE_MAX) ? 0 : eidx + 1;

	/* populate vs_eng_ctx_t */
	eng_ctx->vse_eidx = eidx;
	eng_ctx->vse_cidx = cidx;
	(void) strlcpy(eng_ctx->vse_engid, eng->vse_cfg.vep_engid,
	    sizeof (eng_ctx->vse_engid));
	(void) strlcpy(eng_ctx->vse_host, eng->vse_cfg.vep_host,
	    sizeof (eng_ctx->vse_host));
	eng_ctx->vse_port = eng->vse_cfg.vep_port;
	eng_ctx->vse_sockfd = cxn->vsc_sockfd;

	if (cxn->vsc_state == VS_ENG_INUSE) {
		(void) pthread_mutex_unlock(&vs_eng_mutex);
		return (0);
	}

	/* state == VS_ENG_RESERVED, need to connect */

	(void) pthread_mutex_unlock(&vs_eng_mutex);

	sockfd = vs_eng_connect(eng_ctx->vse_host, eng_ctx->vse_port);

	/* retry a failed connection once */
	if (sockfd == -1) {
		(void) sleep(1);
		sockfd = vs_eng_connect(eng_ctx->vse_host, eng_ctx->vse_port);
	}

	if (sockfd == -1) {
		syslog(LOG_NOTICE, "Scan Engine - connection error (%s:%d) %s",
		    eng_ctx->vse_host, eng_ctx->vse_port,
		    errno ? strerror(errno) : "");
		vs_eng_set_error(eng_ctx, 1);
		vs_eng_release(eng_ctx);
		return (-1);
	}

	(void) pthread_mutex_lock(&vs_eng_mutex);
	switch (cxn->vsc_state) {
	case VS_ENG_DISCONNECTED:
		/* SHUTDOWN occured */
		(void) pthread_mutex_unlock(&vs_eng_mutex);
		vs_eng_release(eng_ctx);
		return (-1);
	case VS_ENG_RESERVED:
		cxn->vsc_state = VS_ENG_INUSE;
		break;
	case VS_ENG_CLOSE_PENDING:
		/* reconfigure occured. Connection will be closed after use */
		break;
	case VS_ENG_INUSE:
	case VS_ENG_AVAILABLE:
	default:
		ASSERT(0);
		break;
	}

	cxn->vsc_sockfd = sockfd;
	eng_ctx->vse_sockfd = sockfd;

	(void) pthread_mutex_unlock(&vs_eng_mutex);
	return (0);
}
Ejemplo n.º 4
0
void
dtrace_sleep(dtrace_hdl_t *dtp)
{
	dt_proc_hash_t *dph = dtp->dt_procs;
	dtrace_optval_t policy = dtp->dt_options[DTRACEOPT_BUFPOLICY];
	dt_proc_notify_t *dprn;

	hrtime_t earliest = INT64_MAX;
	struct timespec tv;
	hrtime_t now;
	int i;

	for (i = 0; _dtrace_sleeptab[i].dtslt_option < DTRACEOPT_MAX; i++) {
		uintptr_t a = (uintptr_t)dtp + _dtrace_sleeptab[i].dtslt_offs;
		int opt = _dtrace_sleeptab[i].dtslt_option;
		dtrace_optval_t interval = dtp->dt_options[opt];

		/*
		 * If the buffering policy is set to anything other than
		 * "switch", we ignore the aggrate and switchrate -- they're
		 * meaningless.
		 */
		if (policy != DTRACEOPT_BUFPOLICY_SWITCH &&
		    _dtrace_sleeptab[i].dtslt_option != DTRACEOPT_STATUSRATE)
			continue;

		if (*((hrtime_t *)a) + interval < earliest)
			earliest = *((hrtime_t *)a) + interval;
	}

	(void) pthread_mutex_lock(&dph->dph_lock);

	now = gethrtime();

	if (earliest < now) {
		(void) pthread_mutex_unlock(&dph->dph_lock);
		return; /* sleep duration has already past */
	}

#if defined(sun)
	tv.tv_sec = (earliest - now) / NANOSEC;
	tv.tv_nsec = (earliest - now) % NANOSEC;

	/*
	 * Wait for either 'tv' nanoseconds to pass or to receive notification
	 * that a process is in an interesting state.  Regardless of why we
	 * awaken, iterate over any pending notifications and process them.
	 */
	(void) pthread_cond_reltimedwait_np(&dph->dph_cv, &dph->dph_lock, &tv);
#else
	earliest -= now;
	clock_gettime(CLOCK_REALTIME,&tv);
	tv.tv_sec += earliest / NANOSEC;
	tv.tv_nsec += earliest % NANOSEC;
	while (tv.tv_nsec > NANOSEC) {
		tv.tv_sec += 1;
		tv.tv_nsec -= NANOSEC;
	}

	/*
	 * Wait for either 'tv' nanoseconds to pass or to receive notification
	 * that a process is in an interesting state.  Regardless of why we
	 * awaken, iterate over any pending notifications and process them.
	 */
	(void) pthread_cond_timedwait(&dph->dph_cv, &dph->dph_lock, &tv);
#endif

	while ((dprn = dph->dph_notify) != NULL) {
		if (dtp->dt_prochdlr != NULL) {
			char *err = dprn->dprn_errmsg;
			if (*err == '\0')
				err = NULL;

			dtp->dt_prochdlr(dprn->dprn_dpr->dpr_proc, err,
			    dtp->dt_procarg);
		}

		dph->dph_notify = dprn->dprn_next;
		dt_free(dtp, dprn);
	}

	(void) pthread_mutex_unlock(&dph->dph_lock);
}