Ejemplo n.º 1
0
static ssize_t
extract_read_callback(struct archive *arc, void *ctx, const void **buf)
{
	pc_ctx_t *pctx = (pc_ctx_t *)ctx;

	if (pctx->arc_closed) {
		pctx->arc_buf_size = 0;
		log_msg(LOG_WARN, 0, "End of file.");
		archive_set_error(arc, ARCHIVE_EOF, "End of file.");
		return (-1);
	}

	if (!pctx->arc_writing) {
		Sem_Wait(&(pctx->read_sem));
	} else {
		Sem_Post(&(pctx->write_sem));
		Sem_Wait(&(pctx->read_sem));
	}

	if (pctx->arc_buf == NULL || pctx->arc_buf_size == 0) {
		pctx->arc_buf_size = 0;
		log_msg(LOG_ERR, 0, "End of file when extracting archive.");
		archive_set_error(arc, ARCHIVE_EOF, "End of file when extracting archive.");
		return (-1);
	}
	pctx->arc_writing = 1;
	*buf = pctx->arc_buf;

	return (pctx->arc_buf_size);
}
Ejemplo n.º 2
0
static void *barber_work(void *arg)
{
    struct barber *barber = arg;
    struct chairs *chairs = &barber->simulator->chairs;
    struct customer *customer = 0; 

    /* Main barber loop */
    while (true) {
		Sem_Wait(&chairs->barber); 
		Sem_Wait(&chairs->mutex);
        /* Incrementing rear by one and modulo max to return back to 0 if
        * the que is at max index */
		customer = chairs->customer[chairs->r++ % chairs->max]; 
        thrlab_prepare_customer(customer, barber->room);
		Sem_Post(&chairs->mutex);
		Sem_Post(&chairs->chair);
		
        thrlab_sleep(5 * (customer->hair_length - customer->hair_goal));
        thrlab_dismiss_customer(customer, barber->room);
		Sem_Post(&customer->mutex);
    }
    return NULL;
}
Ejemplo n.º 3
0
/**
 * Called in a new thread each time a customer has arrived.
 */
static void customer_arrived(struct customer *customer, void *arg)
{
    struct simulator *simulator = arg;
    struct chairs *chairs = &simulator->chairs;

    Sem_Init(&customer->mutex, 0, 0);

    /* If a chair is available we let the customer in, else we turn the
     * customer away. */
    if (sem_trywait(&chairs->chair) == 0) {
        Sem_Wait(&chairs->mutex);
        thrlab_accept_customer(customer);
        /* Incrementing front by one and modulo max to return back to 0 if
         * the que is at max index. */
        chairs->customer[chairs->f++ % chairs->max] = customer;
        Sem_Post(&chairs->mutex);
        Sem_Post(&chairs->barber);
        Sem_Wait(&customer->mutex);
    } else {
        thrlab_reject_customer(customer);
    }
    /* Destroying the customer semaphore */
    Sem_Destroy(&customer->mutex);
}
Ejemplo n.º 4
0
int64_t
archiver_write(void *ctx, void *buf, uint64_t count)
{
	pc_ctx_t *pctx = (pc_ctx_t *)ctx;

	if (pctx->arc_closed) {
		log_msg(LOG_WARN, 0, "Archive extractor closed unexpectedly");
		return (0);
	}

	if (pctx->arc_buf != NULL) {
		log_msg(LOG_ERR, 0, "Incorrect sequencing of archiver_read() call.");
		return (-1);
	}

	pctx->arc_buf = buf;
	pctx->arc_buf_size = count;
	Sem_Post(&(pctx->read_sem));
	Sem_Wait(&(pctx->write_sem));
	pctx->arc_buf = NULL;
	return (pctx->arc_buf_size);
}
Ejemplo n.º 5
0
int64_t
archiver_read(void *ctx, void *buf, uint64_t count)
{
	pc_ctx_t *pctx = (pc_ctx_t *)ctx;

	if (pctx->arc_closed)
		return (0);

	if (pctx->arc_buf != NULL) {
		log_msg(LOG_ERR, 0, "Incorrect sequencing of archiver_read() call.");
		return (-1);
	}

	pctx->arc_buf = buf;
	pctx->arc_buf_size = count;
	pctx->arc_buf_pos = 0;
	pctx->btype = TYPE_UNKNOWN;
	Sem_Post(&(pctx->write_sem));
	Sem_Wait(&(pctx->read_sem));
	pctx->arc_buf = NULL;
	return (pctx->arc_buf_pos);
}
Ejemplo n.º 6
0
static ssize_t
creat_write_callback(struct archive *arc, void *ctx, const void *buf, size_t len)
{
	uchar_t *buff = (uchar_t *)buf;
	pc_ctx_t *pctx = (pc_ctx_t *)ctx;
	size_t remaining;

	if (pctx->arc_closed) {
		archive_set_error(arc, ARCHIVE_EOF, "End of file when writing archive.");
		return (-1);
	}

	if (!pctx->arc_writing) {
		Sem_Wait(&(pctx->write_sem));
	}

	if (pctx->arc_buf == NULL || pctx->arc_buf_size == 0) {
		archive_set_error(arc, ARCHIVE_EOF, "End of file when writing archive.");
		return (-1);
	}
	pctx->arc_writing = 1;

	remaining = len;
	while (remaining && !pctx->arc_closed) {
		uchar_t *tbuf;

		tbuf = pctx->arc_buf + pctx->arc_buf_pos;

		/*
		 * Determine if we should return the accumulated data to the caller.
		 * This is done if the data type changes and at least some minimum amount
		 * of data has accumulated in the buffer.
		 */
		if (pctx->btype != pctx->ctype) {
			if (pctx->btype == TYPE_UNKNOWN || pctx->arc_buf_pos == 0) {
				pctx->btype = pctx->ctype;
			} else {
				if (pctx->arc_buf_pos < pctx->min_chunk) {
					uint32_t diff = pctx->min_chunk - pctx->arc_buf_pos;
					if (len > diff)
						pctx->btype = pctx->ctype;
					else
						pctx->ctype = pctx->btype;
				} else {
					pctx->arc_writing = 0;
					Sem_Post(&(pctx->read_sem));
					Sem_Wait(&(pctx->write_sem));
					tbuf = pctx->arc_buf + pctx->arc_buf_pos;
					pctx->arc_writing = 1;
					if (remaining > 0)
						pctx->btype = pctx->ctype;
				}
			}
		}

		if (remaining > pctx->arc_buf_size - pctx->arc_buf_pos) {
			size_t nlen = pctx->arc_buf_size - pctx->arc_buf_pos;
			memcpy(tbuf, buff, nlen);
			remaining -= nlen;
			pctx->arc_buf_pos += nlen;
			buff += nlen;
			pctx->arc_writing = 0;
			Sem_Post(&(pctx->read_sem));
			Sem_Wait(&(pctx->write_sem));
			pctx->arc_writing = 1;
		} else {
			memcpy(tbuf, buff, remaining);
			pctx->arc_buf_pos += remaining;
			remaining = 0;
			if (pctx->arc_buf_pos == pctx->arc_buf_size) {
				pctx->arc_writing = 0;
				Sem_Post(&(pctx->read_sem));
			}
			break;
		}
	}

	return (len - remaining);
}
Ejemplo n.º 7
0
PAL_Uint32 THREAD_API fireindication(void* param)
{
    Config* config = (Config*)param;
    MI_Result r = MI_RESULT_OK;
    MI_Uint32 failAfterCount = config->failAfterCount;
    MI_Result failResult = config->failResult;

    Atomic_Swap( &config->threadrunning, 1);
    LOGMSG(("Set threadrunning to 1 for config (%p)", config));

    config->count = 0;
    LOGMSG(("Start to fireindication for class (%s)", config->className));

    /* wait for the semaphore */
    LOGMSG(("Wait for semaphore to fire indication"));
    Sem_Wait(&config->sem);
    LOGMSG(("Received semaphore and start firing indication"));

    if (config->testGroup == (MI_Uint32)TestGroup_Misc)
    {
        switch (config->miscTestSubGroup)
        {
        case MiscTestGroup_GetExpression:
        case MiscTestGroup_Evaluate:
        case MiscTestGroup_SelfTest:
            failAfterCount = 1;
            failResult = MI_RESULT_FAILED;
            break;
        default:
            break;
        }
    }

    while((MI_FALSE == config->disabled) && (config->count < failAfterCount))
    {
        config->count++;

        if (config->intervalMS > 0)
        {
            Sleep_Milliseconds(config->intervalMS);
        }
        if (r!= MI_RESULT_OK)
        {
            LOGMSG(("Set property value of indication failed (%d); Ignore #%d indication", r, config->count));
            continue;
        }
        if (config->lifecycleThreadControl == 0)
        {
            const MI_Char* bookmark = NULL;

            DEBUG_ASSERT( NULL != config->setprop );
            r = config->setprop(config->context, &config->indication);
            if (r == MI_RESULT_OK)
            {
                DEBUG_ASSERT( NULL != config->indication );

                if (config->subscribeBookmark &&
                    0 < Strlen(config->subscribeBookmark) &&
                    0 != Strcmp(config->subscribeBookmark, "."))
                {
                    // Only set bookmark if it is non-NULL and non-default
                    bookmark = ansiToMI(config->subscribeBookmark);
                }
                r = MI_Context_PostIndication(config->postctx, config->indication, 0, bookmark);
                if (r!= MI_RESULT_OK)
                {
                    LOGMSG(("Post #%d Indication failed (%d)", config->count, r));
                }

                /* Delete indication instance */
                MI_Instance_Delete( config->indication );
                config->indication = NULL;
            }
            else
            {
                LOGMSG(("config(%p:%s)->setprop failed to create indication instance(%d)", config, config->className, r));
            }
        }
        else
        {
            if (config->lifecycleContext && config->currentSubscriptionTypes != 0 && config->supportedSubscriptionTypes != 0)
            {
                // lifeCycleThreadControl other than 0 and a running thread indicates that we should schedule lifecycle events
                if (config->lifecycleThreadControl & MI_LIFECYCLE_INDICATION_CREATE)
                {
                    r = lifecycle_CreateInstance(config, config->lifecycleInstance);
                    if (r != MI_RESULT_OK)
                    {
                        LOGMSG(("Lifecycle_CreateInstance for class (%s) failed with result (%d)", config->className, r));
                    }
                }
                if (config->lifecycleThreadControl & MI_LIFECYCLE_INDICATION_MODIFY)
                {
                    r = lifecycle_ModifyInstance(config->lifecycleInstance, config);
                    if (r != MI_RESULT_OK)
                    {
                        LOGMSG(("Lifecycle_ModifyInstance for class (%s) failed with result (%d)", config->className, r));
                    }
                }
                if (config->lifecycleThreadControl & MI_LIFECYCLE_INDICATION_DELETE)
                {
                    r = lifecycle_DeleteInstance(config);
                    if (r != MI_RESULT_OK)
                    {
                        LOGMSG(("Lifecycle_DeleteInstance for class (%s) failed with result (%d)", config->className, r));
                    }
                }
                if (config->lifecycleThreadControl & MI_LIFECYCLE_INDICATION_READ)
                {
                    r = lifecycle_EnumerateInstances(config);
                    if (r != MI_RESULT_OK)
                    {
                        LOGMSG(("Lifecycle_EnumerateInstances for class (%s) failed with result (%d)", config->className, r));
                    }
                }
                if (config->lifecycleThreadControl & MI_LIFECYCLE_INDICATION_METHODCALL)
                {
                    r = lifecycle_InvokeMethod(config);
                    if (r != MI_RESULT_OK)
                    {
                        LOGMSG(("Lifecycle_InvokeMethod for class (%s) failed with result (%d)", config->className, r));
                    }
                }
            }
        }
        LOGMSG(("Fired #%d indication for class (%s)", config->count, config->className));
    }

    Atomic_Swap( &config->threadrunning, 0);
    LOGMSG(("Set threadrunning to 0 for config (%p)", config));

    if (MI_FALSE == config->disabled)
    {
        LOGMSG(("fireindication stopped due to class (%s) need to fail after firing (%d) indicaitons", config->className, failAfterCount));
#if !defined(_MSC_VER)
        // if not joined yet, release thread resources
        pthread_detach(config->thread.__impl);
# endif
        if (failResult != MI_RESULT_OK)
        {
            if (config->lifecycleThreadControl == 0)
            {
                MI_Context_PostResult(config->postctx, failResult);
            }
            else
            {
                MI_LifecycleIndicationContext_PostResult(config->lifecycleContext, failResult);
            }
            LOGMSG(("Stop the fireindication and failed the operation with error (%s:%d)", config->className, failResult));
        }
    }
    else
        LOGMSG(("fireindication stopped due to disable indication called"));
    LOGMSG(("Done fireindication for class (%s)", config->className));
    return 0;
}
Ejemplo n.º 8
0
PAL_Uint32 THREAD_API fireLifecycleEvents(void* param)
{
    MI_Result r = MI_RESULT_OK;
    Config* config = (Config*)param;
    LifecycleEvent* event = NULL;
    while (MI_FALSE == config->lifecycleThreadDisabled)
    {
        Sem_Wait(&config->lifecycleQueue.sem);
        event = LifecycleEventQueue_Remove(&config->lifecycleQueue);
        if (event)
        {
            switch (event->type)
            {
            case MI_LIFECYCLE_INDICATION_CREATE:
                if (config->lifecycleContext && (config->currentSubscriptionTypes & config->supportedSubscriptionTypes & MI_LIFECYCLE_INDICATION_CREATE))
                {
                    r = MI_LifecycleIndicationContext_PostCreate(config->lifecycleContext, event->sourceInstance);
                    if (r != MI_RESULT_OK)
                    {
                        LOGMSG(("MI_LifecycleIndicationContext_PostCreate for class (%s) failed with result (%d)", config->className, r));
                    }
                }
                break;
            case MI_LIFECYCLE_INDICATION_MODIFY:
                if (config->lifecycleContext && (config->currentSubscriptionTypes & config->supportedSubscriptionTypes & MI_LIFECYCLE_INDICATION_MODIFY))
                {
                    r = MI_LifecycleIndicationContext_PostModify(config->lifecycleContext, event->previousInstance, event->sourceInstance);
                    if (r != MI_RESULT_OK)
                    {
                        LOGMSG(("MI_LifecycleIndicationContext_PostModify for class (%s) failed with result (%d)", config->className, r));
                    }
                }
                break;
            case MI_LIFECYCLE_INDICATION_DELETE:
                if (config->lifecycleContext && (config->currentSubscriptionTypes & config->supportedSubscriptionTypes & MI_LIFECYCLE_INDICATION_DELETE))
                {
                    r = MI_LifecycleIndicationContext_PostDelete(config->lifecycleContext, event->sourceInstance);
                    if (r != MI_RESULT_OK)
                    {
                        LOGMSG(("MI_LifecycleIndicationContext_PostDelete for class (%s) failed with result (%d)", config->className, r));
                    }
                }
                break;
            case MI_LIFECYCLE_INDICATION_READ:
                if (config->lifecycleContext && (config->currentSubscriptionTypes & config->supportedSubscriptionTypes & MI_LIFECYCLE_INDICATION_READ))
                {
                    r = MI_LifecycleIndicationContext_PostRead(config->lifecycleContext, event->sourceInstance);
                    if (r != MI_RESULT_OK)
                    {
                        LOGMSG(("MI_LifecycleIndicationContext_PostRead for class (%s) failed with result (%d)", config->className, r));
                    }
                }
                break;
            case MI_LIFECYCLE_INDICATION_METHODCALL:
                if (config->lifecycleContext && (config->currentSubscriptionTypes & config->supportedSubscriptionTypes & MI_LIFECYCLE_INDICATION_METHODCALL))
                {
                    r = MI_LifecycleIndicationContext_PostMethodCall_Before(config->lifecycleContext, event->sourceInstance, MI_T("GenericInstMethod"), event->methodParam);
                    if (r != MI_RESULT_OK)
                    {
                        LOGMSG(("MI_LifecycleIndicationContext_PostMethodCall_Before for class (%s) failed with result (%d)", config->className, r));
                    }
                    r = MI_LifecycleIndicationContext_PostMethodCall_After(config->lifecycleContext, event->sourceInstance, MI_T("GenericInstMethod"), event->methodParam, MI_T("0"));
                    if (r != MI_RESULT_OK)
                    {
                        LOGMSG(("MI_LifecycleIndicationContext_PostMethodCall_After for class (%s) failed with result (%d)", config->className, r));
                    }
                }
                break;
            default:
                break;
            }

            LifecycleEvent_Free(event);
        }
    }
    return 0;
}