v_handleResult v_handleRenew( v_handle *handle) { v_handleServer server; v_handleInfo *info; c_long idx; v_handleInfo *block; server = v_handleServer((c_object)handle->server); if (server == NULL) { return V_HANDLE_ILLEGAL; } assert(C_TYPECHECK(server,v_handleServer)); c_mutexLock(&server->mutex); if(server->suspended == TRUE) { return V_HANDLE_SUSPENDED; } idx = handle->index; if ((idx < 0) || (idx > server->lastIndex)) { return V_HANDLE_ILLEGAL; } block = ((v_handleInfo**)server->handleInfos)[COL(idx)]; info = &block[ROW(idx)]; c_mutexLock(&info->mutex); c_mutexUnlock(&server->mutex); info->count = 0; info->serial = (info->serial + 1) % MAXSERIAL; handle->serial = info->serial; c_mutexUnlock(&info->mutex); return V_HANDLE_OK; }
v_handleResult v_handleRelease ( v_handle handle) { v_handleInfo *info; v_handleResult result; result = v_handleServerInfo(handle, &info); if (result == V_HANDLE_OK) { assert(info != NULL); assert(info->count > 0); info->count--; #if CHECK_REF if (v_object(info->object)->kind == CHECK_REF_TYPE) { UT_TRACE("\n\n=========== Release (0x%x): %d -> %d ============\n", info->object, info->count+1, info->count); } #endif if (info->count == 0) { if (info->freed) { /* at this point the handle was deregistered but could not * be invalidated because it was claimed, so it must be invalidated now. */ v_handleInvalidate(handle,info); } else { c_mutexUnlock(&info->mutex); } } else { c_mutexUnlock(&info->mutex); } } return result; }
v_subscriber v_participantGetBuiltinSubscriber( v_participant p) { v_subscriberQos sQos; v_readerQos rQos; v_kernel kernel; c_bool create_builtin_readers = FALSE; assert(p != NULL); assert(C_TYPECHECK(p, v_participant)); c_mutexLock(&p->builtinLock); if (p->builtinSubscriber == NULL) { kernel = v_objectKernel(p); sQos = v_subscriberQosNew(kernel, NULL); sQos->presentation.access_scope = V_PRESENTATION_TOPIC; c_free(sQos->partition); sQos->partition = c_stringNew(c_getBase(c_object(kernel)), V_BUILTIN_PARTITION); sQos->entityFactory.autoenable_created_entities = TRUE; p->builtinSubscriber = v_subscriberNew(p, V_BUILTINSUBSCRIBER_NAME, sQos, TRUE); v_subscriberQosFree(sQos); create_builtin_readers = TRUE; c_mutexUnlock(&p->builtinLock); assert(p->builtinSubscriber != NULL); rQos = v_readerQosNew(kernel, NULL); rQos->durability.kind = V_DURABILITY_TRANSIENT; rQos->reliability.kind = V_RELIABILITY_RELIABLE; rQos->history.kind = V_HISTORY_KEEPLAST; rQos->history.depth = 1; #define _CREATE_READER_(topicName) {\ q_expr expr; \ v_dataReader dr; \ expr = q_parse("select * from " topicName);\ dr = v_dataReaderNew(p->builtinSubscriber, topicName "Reader", \ expr, NULL, rQos, TRUE);\ c_free(dr); \ q_dispose(expr); \ } _CREATE_READER_(V_PARTICIPANTINFO_NAME) _CREATE_READER_(V_TOPICINFO_NAME) _CREATE_READER_(V_PUBLICATIONINFO_NAME) _CREATE_READER_(V_SUBSCRIPTIONINFO_NAME) #undef _CREATE_READER_ v_readerQosFree(rQos); } else { c_mutexUnlock(&p->builtinLock); } return c_keep(p->builtinSubscriber); }
void v_leaseManagerDeinit( v_leaseManager _this) { v_leaseAction lease; assert(C_TYPECHECK(_this, v_leaseManager)); c_mutexLock(&_this->mutex); c_free(_this->firstLeaseToExpire); _this->firstLeaseToExpire = NULL; lease = v_leaseAction(c_take(_this->leases)); while (lease != NULL) { c_free(lease); lease = v_leaseAction(c_take(_this->leases)); } c_free(_this->leases); _this->leases = NULL; _this->quit = TRUE; c_condBroadcast(&_this->cond); c_mutexUnlock(&_this->mutex); /* Note the condition _this->cond is deinitalised via c_free */ }
v_handleResult v_handleDeregister( v_handle handle) { v_handleInfo *info; v_handleResult result; result = v_handleServerInfo(handle, &info); if (result == V_HANDLE_OK) { assert(info != NULL); if (info->count > 0) { /* The handle can not be invalidated yet because it is in use. * so set the free attribute, the v_handleRelease method will * check this flag and invalidate the handle as soon as it is * no longer used. */ info->freed = TRUE; c_mutexUnlock(&info->mutex); } else { v_handleInvalidate(handle,info); } } return result; }
v_result v_deliveryWaitListIgnore ( v_deliveryWaitList _this, v_gid readerGID) { c_ulong size, i, count; v_gid *list; assert(C_TYPECHECK(_this,v_deliveryWaitList)); count = 0; size = c_arraySize(_this->readerGID); list = (v_gid *)_this->readerGID; for (i=0; i<size; i++) { if (v_gidEqual(list[i],readerGID)) { /* Set the found reader gid to zero, * iThe waitlist can be unblocked when * all expected systemIds are zero. * In that case count will be 0. */ v_gidSetNil(list[i]); } count += v_gidSystemId(list[i]); } if (count == 0) { c_free(_this->readerGID); _this->readerGID = NULL; c_mutexLock(&_this->mutex); c_condSignal(&_this->cv); c_mutexUnlock(&_this->mutex); } return V_RESULT_OK; }
static void nw_messageBoxPushMessage( nw_messageBox messageBox, nw_networkId networkId, os_sockaddr_storage address, c_string list, nw_messageBoxMessageType messageType) { nw_messageBoxMessage newMessage; nw_messageBoxMessage *prevNextPtr; c_mutexLock(&messageBox->mutex); newMessage = (nw_messageBoxMessage)os_malloc(sizeof(*newMessage)); newMessage->networkId = networkId; newMessage->address = address; newMessage->list = list; newMessage->messageType = messageType; if (messageBox->firstMessage == NULL) { prevNextPtr = &(messageBox->firstMessage); } else { prevNextPtr = &(messageBox->lastMessage->next); } newMessage->next = NULL; *prevNextPtr = newMessage; messageBox->lastMessage = newMessage; c_mutexUnlock(&(messageBox->mutex)); }
void v_leaseUnlock( v_lease _this) { assert(_this); assert(C_TYPECHECK(_this, v_lease)); c_mutexUnlock(&_this->mutex); }
void v_participantConnectNewGroup ( v_participant _this, v_event event) { v_group g; c_mutexLock(&_this->newGroupListMutex); g = c_take(_this->newGroupList); while (g) { c_mutexUnlock(&_this->newGroupListMutex); c_lockWrite(&_this->lock); c_walk(_this->entities, connectNewGroup, g); c_lockUnlock(&_this->lock); c_mutexLock(&_this->newGroupListMutex); g = c_take(_this->newGroupList); } c_mutexUnlock(&_this->newGroupListMutex); }
/* Do not use C_TYPECHECK on qos parameter, since it might be allocated on heap! */ kernel = v_objectKernel(p); c_lockWrite(&p->lock); result = v_participantQosSet(p->qos, qos, &cm); if ((result == V_RESULT_OK) && (cm != 0)) { builtinMsg = v_builtinCreateParticipantInfo(kernel->builtin,p); c_lockUnlock(&p->lock); v_writeBuiltinTopic(kernel, V_PARTICIPANTINFO_ID, builtinMsg); c_free(builtinMsg); } else { c_lockUnlock(&p->lock); } return result; } v_leaseManager v_participantGetLeaseManager( v_participant p) { assert(C_TYPECHECK(p,v_participant)); return c_keep(p->leaseManager); } #define RESEND_SECS (0U) #define RESEND_NANOSECS (2000000U) /* 2 ms */ void v_participantResendManagerMain( v_participant p) { c_iter writerProxies; v_proxy wp; v_writer w; v_handleResult r; c_time waitTime = { RESEND_SECS, RESEND_NANOSECS }; assert(C_TYPECHECK(p,v_participant)); c_mutexLock(&p->resendMutex); while (!p->resendQuit) { if (c_count(p->resendWriters) == 0) { c_condWait(&p->resendCond, &p->resendMutex); } else { c_condTimedWait(&p->resendCond, &p->resendMutex, waitTime); } if (!p->resendQuit) { writerProxies = c_select(p->resendWriters, 0); c_mutexUnlock(&p->resendMutex); wp = v_proxy(c_iterTakeFirst(writerProxies)); while (wp != NULL) { r = v_handleClaim(wp->source,(v_object *)&w); if (r == V_HANDLE_OK) { assert(C_TYPECHECK(w,v_writer)); v_writerResend(w); v_handleRelease(wp->source); } c_free(wp); wp = v_proxy(c_iterTakeFirst(writerProxies)); } c_iterFree(writerProxies); c_mutexLock(&p->resendMutex); } /* already quiting */ } c_mutexUnlock(&p->resendMutex); }
void v_networkQueueTrigger( v_networkQueue queue) { c_mutexLock(&queue->mutex); queue->triggered = 1; if (queue->threadWaiting) { c_condBroadcast(&queue->cv); } c_mutexUnlock(&queue->mutex); }
void v_participantResendManagerQuit( v_participant p) { assert(C_TYPECHECK(p,v_participant)); c_mutexLock(&p->resendMutex); p->resendQuit = TRUE; c_condBroadcast(&p->resendCond); c_mutexUnlock(&p->resendMutex); }
void v_observerFree( v_observer o) { assert(C_TYPECHECK(o,v_observer)); c_mutexLock(&o->mutex); o->eventFlags |= V_EVENT_OBJECT_DESTROYED; c_condBroadcast(&o->cv); c_mutexUnlock(&o->mutex); v_observableFree(v_observable(o)); }
c_bool v_partitionAdminFitsInterest( v_partitionAdmin da, v_partition d) { c_bool result; c_mutexLock(&da->mutex); result = !c_tableWalk(da->partitionInterests, checkPartitionInterest, d); c_mutexUnlock(&da->mutex); return result; }
/** * This method will invalidate a handle and mark the resources as ready for reuse. * Note that the info and handle musr correspond and that info is locked. */ static void v_handleInvalidate ( v_handle handle, v_handleInfo *info) { v_handleServer server; c_object entity; server = v_handleServer((c_object)handle.server); assert(C_TYPECHECK(server,v_handleServer)); if (server) { c_mutexLock(&server->mutex); info->nextFree = server->firstFree; server->firstFree = handle.index; info->serial = (info->serial + 1) % MAXSERIAL; entity = info->object; info->object = NULL; c_mutexUnlock(&server->mutex); c_mutexUnlock(&info->mutex); v_publicDispose(v_public(entity)); } }
v_handleResult v_handleClaim ( v_handle handle, v_object *o) { v_handleInfo *info; v_handleResult result; v_handleServer server; server = v_handleServer((c_object)handle.server); if (server == NULL) { return V_HANDLE_ILLEGAL; } if(server->suspended == TRUE) { /* For now the suspended state means that an unrecoverable error has * occured. This implies that from now on any access to the kernel is * unsafe and the result is undefined. * So because of this skip this action and return NULL. */ return V_HANDLE_SUSPENDED; } result = v_handleServerInfo(handle, &info); if (result != V_HANDLE_OK) { *o = NULL; return result; } if (info->freed) { /* Too late, it is already being freed... */ result = V_HANDLE_EXPIRED; *o = NULL; } else { info->count++; #if CHECK_REF if (v_object(info->object)->kind == CHECK_REF_TYPE) { UT_TRACE("\n\n============ Claim (0x%x): %d -> %d =============\n", info->object, info->count -1, info->count); } #endif *o = (v_object)info->object; if(*o == NULL) { OS_REPORT(OS_WARNING, "v_handleClaim", 0, "Unable to obtain kernel entity for handle"); result = V_HANDLE_ILLEGAL; } } c_mutexUnlock(&info->mutex); return result; }
c_ulong v_observerWait( v_observer o) { c_ulong flags; assert(o != NULL); assert(C_TYPECHECK(o,v_observer)); c_mutexLock(&o->mutex); flags = v__observerWait(o); c_mutexUnlock(&o->mutex); return flags; }
void v_participantResendManagerRemoveWriter( v_participant p, v_writer w) { C_STRUCT(v_proxy) wp; v_proxy found; wp.source = v_publicHandle(v_public(w)); wp.userData = NULL; c_mutexLock(&p->resendMutex); found = c_remove(p->resendWriters, &wp, NULL, NULL); c_free(found); /* remove local reference transferred from collection */ c_mutexUnlock(&p->resendMutex); }
c_ulong v_observerGetEventMask( v_observer o) { c_ulong eventMask; assert(o != NULL); assert(C_TYPECHECK(o,v_observer)); c_mutexLock(&o->mutex); eventMask = o->eventMask; c_mutexUnlock(&o->mutex); return eventMask; }
c_ulong v_observerTimedWait( v_observer o, const c_time time) { c_ulong flags; assert(o != NULL); assert(C_TYPECHECK(o,v_observer)); c_mutexLock(&o->mutex); flags = v__observerTimedWait(o, time); c_mutexUnlock(&o->mutex); return flags; }
void v_participantNotify( v_participant _this, v_event event, c_voidp userData) { /* This Notify method is part of the observer-observable pattern. * It is designed to be invoked when _this object as observer receives * an event from an observable object. * It must be possible to pass the event to the subclass of itself by * calling <subclass>Notify(_this, event, userData). * This implies that _this as observer cannot be locked within any * Notify method to avoid deadlocks. * For consistency _this must be locked by v_observerLock(_this) before * calling this method. */ assert(_this != NULL); assert(C_TYPECHECK(_this,v_participant)); if (event) { switch (event->kind) { case V_EVENT_NEW_GROUP: assert(event->userData); c_mutexLock(&_this->newGroupListMutex); c_listInsert(_this->newGroupList,v_group(event->userData)); c_mutexUnlock(&_this->newGroupListMutex); break; case V_EVENT_LIVELINESS_ASSERT: c_lockWrite(&_this->lock); c_walk(_this->entities, assertLivelinessPublisher, event); c_lockUnlock(&_this->lock); break; case V_EVENT_SERVICESTATE_CHANGED: case V_EVENT_DATA_AVAILABLE: case V_EVENT_HISTORY_DELETE: case V_EVENT_HISTORY_REQUEST: case V_EVENT_PERSISTENT_SNAPSHOT: /*Do nothing here.*/ break; default: OS_REPORT_1(OS_WARNING,"v_participantNotify",0, "Notify encountered unknown event kind (%d)", event->kind); break; } } }
c_bool v_leaseManagerNotify( v_leaseManager _this, v_lease lease, v_eventKind event) { struct findLeaseActionArg arg; assert(_this != NULL); assert(C_TYPECHECK(_this, v_leaseManager)); c_mutexLock(&_this->mutex); if (event & V_EVENT_LEASE_RENEWED) { if (_this->firstLeaseToExpire) { if (_this->firstLeaseToExpire->lease == lease) { /* If the lease is the head we are forced to wake-up the thread, since we do not know the remaining sleeptime of the thread. */ c_condBroadcast(&_this->cond); } else { arg.lease = lease; arg.action = NULL; c_setWalk(_this->leases, findLeaseAction, &arg); if (arg.action) { /* determine if this is the new head */ if (c_timeCompare(v_leaseExpiryTime(_this->firstLeaseToExpire->lease), v_leaseExpiryTime(lease)) == C_GT) { c_free(_this->firstLeaseToExpire); _this->firstLeaseToExpire = c_keep(arg.action); c_condBroadcast(&_this->cond); } c_free(arg.action); } /* else lease is not registered, so no interest in this update! */ } } } else { if (event & V_EVENT_TERMINATE) { _this->quit = TRUE; c_condBroadcast(&_this->cond); } } c_mutexUnlock(&_this->mutex); return TRUE; }
c_ulong v_observerClearEvent( v_observer o, c_ulong event) { c_ulong eventMask; assert(o != NULL); assert(C_TYPECHECK(o,v_observer)); c_mutexLock(&o->mutex); eventMask = o->eventMask; o->eventMask &= ~event; c_mutexUnlock(&o->mutex); return eventMask; }
static nw_messageBoxMessage nw_messageBoxPopMessage( nw_messageBox messageBox) { nw_messageBoxMessage result = NULL; c_mutexLock(&(messageBox->mutex)); if (messageBox->firstMessage != NULL) { result = messageBox->firstMessage; messageBox->firstMessage = result->next; if (messageBox->firstMessage == NULL) { messageBox->lastMessage = NULL; } } c_mutexUnlock(&(messageBox->mutex)); return result; }
c_bool v_networkQueueTakeAction( v_networkQueue queue, v_networkQueueAction action, c_voidp arg) { v_networkStatusMarker currentMarker; v_networkQueueSample sample; c_bool proceed = TRUE; c_mutexLock(&queue->mutex); currentMarker = queue->firstStatusMarker; while ((currentMarker != NULL) && proceed) { sample = currentMarker->firstSample; assert(sample != NULL); if (sample != NULL) { proceed = action(sample, arg); queue->currentMsgCount--; /* numberOfSamplesTaken+ & numberOfSamplesWaiting- stats */ v_networkQueueStatisticsAdd(numberOfSamplesTaken,queue->statistics); v_networkQueueStatisticsCounterDec(numberOfSamplesWaiting,queue->statistics); currentMarker->firstSample = sample->next; /* no keep, transfer refCount */ sample->next = queue->freeSamples; queue->freeSamples = sample; if (currentMarker->firstSample == NULL) { currentMarker->lastSample = NULL; queue->firstStatusMarker = currentMarker->next; /* no keep, transfer refCount */ currentMarker->next = queue->freeStatusMarkers; queue->freeStatusMarkers = currentMarker; if (queue->firstStatusMarker == NULL) { queue->lastStatusMarker = NULL; } } } currentMarker = queue->firstStatusMarker; } c_mutexUnlock(&queue->mutex); proceed = action(NULL, arg); return proceed; }
void v_participantResendManagerAddWriter( v_participant p, v_writer w) { v_proxy wp, found; assert(C_TYPECHECK(p,v_participant)); wp = v_proxyNew(v_objectKernel(w), v_publicHandle(v_public(w)), NULL); c_mutexLock(&p->resendMutex); found = c_insert(p->resendWriters, wp); assert((found->source.index == wp->source.index) && (found->source.serial == wp->source.serial)); c_condBroadcast(&p->resendCond); c_mutexUnlock(&p->resendMutex); c_free(wp); }
void v_readerFree( v_reader r) { assert(C_TYPECHECK(r,v_reader)); if (r->subscriber != NULL) { v_subscriberRemoveReader(v_subscriber(r->subscriber),r); c_mutexLock(&(v_observer(r)->mutex)); r->subscriber = NULL; c_mutexUnlock(&(v_observer(r)->mutex)); } /* Free all entries */ v_readerWalkEntries(r, entryFree, NULL); /* Call inherited free */ v_collectionFree(v_collection(r)); }
/** * \brief The HandleServer get handle info method. * * This private method retrieves the handle info structure for the specified handle. * A infor record is only returned for a valid handle. The returned handle info record is locked * before returned so it cannot be modified until the caller unlocks it. */ static v_handleResult v_handleServerInfo( v_handle handle, v_handleInfo **info) { v_handleServer server; c_long idx; v_handleInfo *block; v_handleResult result; server = v_handleServer((c_object)handle.server); if (server == NULL) { *info = NULL; return V_HANDLE_ILLEGAL; } #if 0 if(server->suspended == TRUE) { *info = NULL; return V_HANDLE_SUSPENDED; } #endif idx = handle.index; if ((idx < 0) || (idx > server->lastIndex)) { *info = NULL; return V_HANDLE_ILLEGAL; } block = ((v_handleInfo**)server->handleInfos)[COL(idx)]; *info = &block[ROW(idx)]; c_mutexLock(&(*info)->mutex); if (handle.serial != (*info)->serial) { if (handle.serial < (*info)->serial) { result = V_HANDLE_EXPIRED; } else { result = V_HANDLE_ILLEGAL; } c_mutexUnlock(&(*info)->mutex); *info = NULL; return result; } return V_HANDLE_OK; }
v_result v_deliveryWaitListWait ( v_deliveryWaitList _this, v_duration timeout) { v_result result = V_RESULT_OK; c_syncResult r; assert(C_TYPECHECK(_this,v_deliveryWaitList)); if (_this->readerGID != NULL) { c_mutexLock(&_this->mutex); if(c_timeCompare(timeout, C_TIME_INFINITE) != C_EQ) { r = c_condTimedWait(&_this->cv,&_this->mutex,timeout); } else { r = c_condWait(&_this->cv,&_this->mutex); } c_mutexUnlock(&_this->mutex); switch (r) { case SYNC_RESULT_SUCCESS: result = V_RESULT_OK; break; case SYNC_RESULT_TIMEOUT: result = V_RESULT_TIMEOUT; break; case SYNC_RESULT_UNAVAILABLE: case SYNC_RESULT_BUSY: case SYNC_RESULT_INVALID: case SYNC_RESULT_FAIL: default: result = V_RESULT_PRECONDITION_NOT_MET; break; } } return result; }
void v_listenerFree( v_listener _this) { v_participant p; v_listenerEvent event; os_duration delay; assert(_this != NULL); assert(C_TYPECHECK(_this,v_listener)); p = v_participant(_this->participant); assert(p != NULL); c_mutexLock(&_this->mutex); /* wakeup blocking threads to evaluate new condition. */ /* remove all events */ while (_this->eventList != NULL) { event = _this->eventList; _this->eventList = event->next; v_listenerEventDeinit(event); c_free(event); } _this->eventList = NULL; c_free(_this->lastEvent); _this->lastEvent = NULL; _this->terminate = TRUE; c_condBroadcast(&_this->cv); c_mutexUnlock(&_this->mutex); delay = OS_DURATION_INIT(0, 1000); while (_this->waitCount > 0 && !p->processIsZombie) { ospl_os_sleep(delay); } v_participantRemove(p, v_object(_this)); _this->participant = NULL; v_publicFree(v_public(_this)); }