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); }
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; }
/** * 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); }
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); }
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); }
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); }
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; }
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; }