Esempio n. 1
0
MME_ERROR MME_GetTransformerCapability(const char *name, MME_TransformerCapability_t * capability)
{

	MME_ERROR res;
	Transformer_t *transformer;

#ifndef MME_LEAN_AND_MEAN
        if (manager == NULL) {
                return MME_DRIVER_NOT_INITIALIZED;      /* the manager must exist */
        }

        if (NULL == name || NULL == capability ||
            capability->StructSize != sizeof(MME_TransformerCapability_t)) {
                return MME_INVALID_ARGUMENT;
        }
#endif

	/* protect access */
	EMBX_OS_MUTEX_TAKE(&manager->monitorMutex);	

	/* Find a registered transformer (registered with MME_RegisterTransformer) */
	res = createTransformerInstance(name, &transformer);
	if (MME_SUCCESS == res) {
		EMBX_OS_MUTEX_RELEASE(&manager->monitorMutex);
		res = transformer->vtable->getTransformerCapability(transformer, name, capability);
		EMBX_OS_MUTEX_TAKE(&manager->monitorMutex);	

		transformer->vtable->destroy(transformer);
	}

	EMBX_OS_MUTEX_RELEASE(&manager->monitorMutex);
	return res;
}
Esempio n. 2
0
MME_ERROR MME_KillTransformer(MME_TransformerHandle_t handle)
{
	Transformer_t *transformer;
	MME_ERROR res;

#ifndef MME_LEAN_AND_MEAN
        if (NULL == manager) {
 	        MME_Info( MME_INFO_MANAGER, (DEBUG_ERROR_STR "Driver not initialized\n"));
                return MME_DRIVER_NOT_INITIALIZED;      /* the manager must exist */
        }
#endif

	EMBX_OS_MUTEX_TAKE(&manager->monitorMutex);

	/* Find the transformer */
	res = findTransformerInstance(handle, &transformer);
	if (res != MME_SUCCESS) {
		EMBX_OS_MUTEX_RELEASE(&manager->monitorMutex);
 	        MME_Info( MME_INFO_MANAGER, (DEBUG_ERROR_STR "Failed to find transformer instance\n"));
		return MME_INVALID_HANDLE;
	}

	
	res = transformer->vtable->kill(transformer);
	if (MME_SUCCESS == res) {
		deregisterTransformerInstance(handle);

		transformer->vtable->destroy(transformer);
	}
	
	EMBX_OS_MUTEX_RELEASE(&manager->monitorMutex);
	return res;
}
Esempio n. 3
0
MME_ERROR MME_MessageQueue_Dequeue(MMEMessageQueue * msgQ, void **message)
{
	MMEMessageQueueEntry *entry;

	MME_Info(MME_INFO_QUEUE, (">>>MME_MessageQueue_Dequeue(0x%08x, ...)\n", (unsigned) msgQ));

	sortMessageQueue(msgQ);

	EMBX_OS_MUTEX_TAKE(&msgQ->queueLock);

	/* dequeue the first message */
	entry = msgQ->sorted_front;
	if (NULL == entry) {
		*message = NULL;
		MME_Info(MME_INFO_QUEUE, ("<<<MME_MessageQueue_Dequeue(..., 0x%08x) = MME_INVALID_HANDLE\n",
		                          (unsigned) *message));
		EMBX_OS_MUTEX_RELEASE(&msgQ->queueLock);
		return MME_INVALID_HANDLE;
	}
	msgQ->sorted_front = entry->next;

	/* push it onto the free list */
	entry->next = msgQ->free_list;
	msgQ->free_list = entry;

	*message = entry->message;

	MME_Info(MME_INFO_QUEUE, ("<<<MME_MessageQueue_Dequeue(..., 0x%08x) = MME_SUCCESS\n",
				  (unsigned) *message));
	EMBX_OS_MUTEX_RELEASE(&msgQ->queueLock);
	return MME_SUCCESS;
}
Esempio n. 4
0
MME_ERROR MME_DeregisterTransformer(const char *name)
{
	RegisteredLocalTransformer_t *elem, **prev;

#ifndef MME_LEAN_AND_MEAN
	if (NULL == manager) {
		return MME_DRIVER_NOT_INITIALIZED;
	}

	if (NULL == name) {
		return MME_INVALID_ARGUMENT;
	}
#endif

	EMBX_OS_MUTEX_TAKE(&manager->monitorMutex);

	for (elem = *(prev = &manager->localTransformerList); elem; elem = *(prev = &elem->next)) {
		if (0 == strcmp(name, elem->name)) {
			break;
		}
	}

	if (elem && 0 == elem->inUseCount) {
		*prev = elem->next;
		EMBX_OS_MemFree(elem);

		EMBX_OS_MUTEX_RELEASE(&manager->monitorMutex);
		return MME_SUCCESS;
	}

	EMBX_OS_MUTEX_RELEASE(&manager->monitorMutex);
	return MME_INVALID_ARGUMENT;
}
Esempio n. 5
0
MME_ERROR MME_RegisterTransformer(const char *name,
                                  MME_AbortCommand_t abortCommand,
                                  MME_GetTransformerCapability_t getTransformerCapability,
                                  MME_InitTransformer_t initTransformer,
                                  MME_ProcessCommand_t processCommand,
                                  MME_TermTransformer_t termTransformer)
{
	RegisteredLocalTransformer_t *elem;

#ifndef MME_LEAN_AND_MEAN
	if (NULL == manager) {
		return MME_DRIVER_NOT_INITIALIZED;
	}

	if (NULL == name) {
		return MME_INVALID_ARGUMENT;
	}
#endif

	EMBX_OS_MUTEX_TAKE(&manager->monitorMutex);

	/* check for multiple registrations */
	for (elem = manager->localTransformerList; elem; elem = elem->next) {
		if (0 == strcmp(name, elem->name)) {
			EMBX_OS_MUTEX_RELEASE(&manager->monitorMutex);
			return MME_INVALID_ARGUMENT;
		}
	}

	/* register the transformer */
	elem = EMBX_OS_MemAlloc(sizeof(*elem) + strlen(name) + 1);
	
	/* populate and enqueue the structure */
	elem->name = (char *) (elem + 1);
	strcpy(elem->name, name);

	elem->vtable.AbortCommand = abortCommand;
	elem->vtable.GetTransformerCapability = getTransformerCapability;
	elem->vtable.InitTransformer = initTransformer;
	elem->vtable.ProcessCommand = processCommand;
	elem->vtable.TermTransformer = termTransformer;

	elem->inUseCount = 0;

	elem->next = manager->localTransformerList;
	manager->localTransformerList = elem;

	EMBX_OS_MUTEX_RELEASE(&manager->monitorMutex);
	return MME_SUCCESS;
}
Esempio n. 6
0
MME_ERROR MME_HostRegisterTransport(const char *name)
#endif
{
	MME_ERROR res;
	EMBX_ERROR err;
	TransportInfo_t *tpInfo = 0;

#ifndef MME_LEAN_AND_MEAN
        if (manager == NULL) {
		MME_Info(MME_INFO_MANAGER, (DEBUG_ERROR_STR "MME not initialized\n"));
                return MME_DRIVER_NOT_INITIALIZED;      /* the manager must exist */
        }

	if (name == NULL) {
		MME_Info(MME_INFO_MANAGER, (DEBUG_ERROR_STR "Name not valid\n"));
		return MME_INVALID_ARGUMENT;
	}
#endif

	EMBX_OS_MUTEX_TAKE(&manager->monitorMutex);	

#ifndef MME_LEAN_AND_MEAN
	/* prevent duplicate transport registrations */
	for (tpInfo = manager->transportList; tpInfo; tpInfo = tpInfo->next) {
		EMBX_TPINFO embxTpInfo;

		err = EMBX_GetTransportInfo(tpInfo->handle, &embxTpInfo);
		MME_Assert(EMBX_SUCCESS == err);

		if (0 == strcmp(name, embxTpInfo.name)) {
			EMBX_OS_MUTEX_RELEASE(&manager->monitorMutex);
			MME_Info(MME_INFO_MANAGER, (DEBUG_ERROR_STR "Transport already registered\n"));
			return MME_INVALID_ARGUMENT;
		}
	}
#endif

	/* allocate space for the transport descriptor */
	res = createTransportInfo(name, &tpInfo);
	if (MME_SUCCESS == res) {
		/* update the lists with in the manager */
		tpInfo->next = manager->transportList;
		manager->transportList = tpInfo;
	}

	EMBX_OS_MUTEX_RELEASE(&manager->monitorMutex);
       	MME_Info(MME_INFO_MANAGER, (DEBUG_NOTIFY_STR "<<<< (%d)\n", res));
	return res;
}
Esempio n. 7
0
static void executionLoopTask(void *params)
{
	int id = (int) params;

	for (EMBX_OS_EVENT_WAIT(&(manager->commandEvents[id]));
	     manager->loopTasksRunning[id];
	     EMBX_OS_EVENT_WAIT(&(manager->commandEvents[id]))) {

		MMEReceiver *receiver;
		MMEReceiver *lowestReceiver;
		MME_Time_t dueTime, lowestDueTime;
		int found = 0;

		EMBX_OS_MUTEX_TAKE(&(manager->receiverListMutexes[id]));

		EMBX_OS_MUTEX_TAKE(&(manager->abortMutex));

		/* Find the receiver with the lowest dueTime. */
		lowestReceiver = manager->receiverLists[id];
		lowestDueTime = MME_MaxTime_c;
		for (receiver = lowestReceiver; receiver; receiver = receiver->next) {
			if (MME_SUCCESS == MME_Receiver_NextDueTime(receiver, &dueTime)) {
				if (dueTime < lowestDueTime) {
					found = 1;
					lowestReceiver = receiver;
					lowestDueTime = dueTime;
				}
			}
		}

		/* TODO: Note that if we support the bufferQueue, we need to serve it here */
		if (found) {
			EMBX_OS_MUTEX_RELEASE(&(manager->receiverListMutexes[id]));
			/* Execute this receiver's command. */
			/* Mutex will be released once the message is dequeued - otherwise
			   an abort requiest may come take the message off the queue
                           but leave the receiver in the executing state 
                        */
			MME_Receiver_ProcessCommand(lowestReceiver);
		} else {
			/* Nothing is pending. We could waste some time. */
			MME_Info(MME_INFO_MANAGER, ("Execution loop error: Semaphore signalled but no command found!\n"));
			EMBX_OS_MUTEX_RELEASE(&(manager->receiverListMutexes[id]));

			EMBX_OS_MUTEX_RELEASE(&(manager->abortMutex));
		}
	}
}
Esempio n. 8
0
MME_ERROR MME_KillCommandAll(MME_TransformerHandle_t handle)
{
	Transformer_t *transformer;
	MME_ERROR result;

#ifndef MME_LEAN_AND_MEAN
	if (NULL == manager) {
		return MME_DRIVER_NOT_INITIALIZED;
	}
#endif

	/* protect access */
	EMBX_OS_MUTEX_TAKE(&manager->monitorMutex);	

	result = findTransformerInstance(handle, &transformer);

	if (result != MME_SUCCESS) {
		/* cannot find transformer for this handle */
		result = MME_INVALID_HANDLE;
		goto EXIT;
	}
	result = transformer->vtable->killCommandAll(transformer);
	if (result != MME_SUCCESS) {
		result = MME_INVALID_ARGUMENT;
		goto EXIT;
	}

	result = MME_SUCCESS;
EXIT:
	EMBX_OS_MUTEX_RELEASE(&manager->monitorMutex);
	return result;
}
Esempio n. 9
0
MME_ERROR MME_MessageQueue_RemoveAll(MMEMessageQueue * msgQ)
{
	MMEMessageQueueEntry **prev;
	int i;

	MME_Info(MME_INFO_QUEUE, (">>>MME_MessageQueue_RemoveAll(0x%08x)\n", (unsigned) msgQ));
	MME_Assert(msgQ);
	MME_Assert(msgQ->maxEntries > 0);

	EMBX_OS_MUTEX_TAKE(&msgQ->queueLock);

	/* initialize the free list */
	for (prev = &(msgQ->free_list), i=0;
	     i < msgQ->maxEntries;
	     prev = &(msgQ->queue[i].next), i++) {
		*prev = &(msgQ->queue[i]);
	}
	*prev = NULL;

	msgQ->sorted_front = 0;
	msgQ->unsorted_front = 0;

	EMBX_OS_MUTEX_RELEASE(&msgQ->queueLock);
	MME_Info(MME_INFO_QUEUE, ("<<<MME_MessageQueue_RemoveAll = MME_SUCCESS\n"));
	return MME_SUCCESS;
}
Esempio n. 10
0
MME_ERROR MME_DeregisterTransformer(const char *name) {
	MME_ERROR result = MME_INVALID_ARGUMENT;
	MMEReceiverFactory *factory, **prev;

	if (NULL == manager) {
		return MME_DRIVER_NOT_INITIALIZED;
	}

	if (NULL == name) {
		return MME_INVALID_ARGUMENT;
	}

	/* iterate over the (singly linked) factory list until we find 
	 * a factory or reach the end
	 */
	EMBX_OS_MUTEX_TAKE(&(manager->factoryListMutex));
	for (prev = &(manager->factoryList), factory = *prev;
	     NULL != factory;
	     prev = &(factory->next), factory = *prev) {
		if (0 == strcmp(factory->transformerType, name)) {
			/* unlink and free the node */
			*prev = factory->next;
			free(factory);

			result = MME_SUCCESS;
			break;
		}
	}
	EMBX_OS_MUTEX_RELEASE(&(manager->factoryListMutex));

	return result;
}
Esempio n. 11
0
EMBX_ERROR EMBX_RemoveProcessor(EMBX_TRANSPORT htp, EMBX_UINT cpuID)
{
    EMBX_ERROR res = EMBX_INVALID_TRANSPORT;

    EMBX_Info(EMBX_INFO_TRANSPORT, (">>>>EMBX_RemoveProcessor(htp=0x%08lx,cpu=%d)\n",(unsigned long)htp, cpuID));
    EMBX_DebugOn(EMBX_INFO_TRANSPORT);

    if(!_embx_dvr_ctx.isLockInitialized)
    {
        EMBX_DebugMessage((_driver_uninit_error));
        goto exit;
    }
    
    if(!EMBX_HANDLE_ISTYPEOF(htp, EMBX_HANDLE_TYPE_TRANSPORT))
    {
	res = EMBX_INVALID_TRANSPORT;
        goto exit;
    }

    EMBX_OS_MUTEX_TAKE(&_embx_dvr_ctx.lock);

    if(_embx_dvr_ctx.state != EMBX_DVR_INITIALIZED &&
       _embx_dvr_ctx.state != EMBX_DVR_IN_SHUTDOWN )
    {
        EMBX_DebugMessage((_driver_uninit_error));
	res = EMBX_INVALID_TRANSPORT;
    }
    else
    {
	EMBX_TransportHandle_t *tph;

	tph = (EMBX_TransportHandle_t *)EMBX_HANDLE_GETOBJ(&_embx_handle_manager, htp);
	if( (tph == 0) || (tph->state != EMBX_HANDLE_VALID) ) 
	{
	    EMBX_DebugMessage(("Failed 'transport handle is not valid'\n"));
	    res = EMBX_INVALID_TRANSPORT;
	}
	else
	{
	    EMBX_Transport_t *tp = tph->transport;

	    EMBX_Assert(tp);
	    EMBX_Assert(tp->methods->remove_processor);
	    
	    /* Call the transport specific removal function */
	    res = tp->methods->remove_processor(tp, cpuID);
	}
    }

    EMBX_OS_MUTEX_RELEASE(&_embx_dvr_ctx.lock);


exit:
    EMBX_DebugOff(EMBX_INFO_TRANSPORT);
    EMBX_Info(EMBX_INFO_TRANSPORT, ("<<<<EMBX_RemoveProcessor(htp=0x%08lx,cpu=%d) = %d\n",
				    (unsigned long)htp, cpuID, res));

    return res;
}
Esempio n. 12
0
static void receiveIsAliveMessage(TransformerIsAliveMessage * message)
{
	EMBX_PORT replyPort = EMBX_INVALID_HANDLE_VALUE;
	EMBX_ERROR err;

	MMEReceiver **prev = NULL, *receiver = NULL;
	int id;

	/* Search each receiver list for a matching handle */
	for (id=0; id<MME_NUM_EXECUTION_LOOPS; id++) {
		if (manager->loopTasksRunning[id]) {
			EMBX_OS_MUTEX_TAKE(&(manager->receiverListMutexes[id]));

			/* iterate of the receiver list keeping track of the linkage pointer */
			for (prev = &(manager->receiverLists[id]), receiver = *prev;
			     NULL != receiver;
			     prev = &(receiver->next), receiver = *prev) {
				if (receiver == (void *) (message->mmeHandle)) {
					/* even Java lets you use labelled jumps to do this ... */
					goto double_break;
				}
			}

			EMBX_OS_MUTEX_RELEASE(&(manager->receiverListMutexes[id]));
		} else {
			MME_Assert(0 == manager->loopTasks[id]);
			MME_Assert(0 == manager->receiverLists[id]);
		}

	}
    double_break:

        /* WARNING: if receiver is non-NULL we still own receiverListMutexes[id] */

	if (NULL != receiver) {
		replyPort = MME_Receiver_GetReplyPort(receiver);
		
		EMBX_OS_MUTEX_RELEASE(&(manager->receiverListMutexes[id]));

		/* send the message back to the host */
		err = EMBX_SendMessage(replyPort, message, message->messageSize);
		MME_Assert(EMBX_SUCCESS == err); /* cannot recover */
	} else {
		MME_Info(MME_INFO_MANAGER, ("receiveIsAliveMessage could not find receiver, no reply port available!\n"));
	}
}
Esempio n. 13
0
MME_ERROR MME_FindTransformerInstance(MME_TransformerHandle_t handle,
                                         Transformer_t** transformer) {
        MME_ERROR error;                                          	
	/* protect access */
	EMBX_OS_MUTEX_TAKE(&manager->monitorMutex);	
	error = findTransformerInstance(handle, transformer);
	EMBX_OS_MUTEX_RELEASE(&manager->monitorMutex);
	return error;
}
Esempio n. 14
0
EMBX_ERROR EMBX_FindTransport(const EMBX_CHAR *name, EMBX_TPINFO *tpinfo)
{
EMBX_ERROR res;

    EMBX_Info(EMBX_INFO_TRANSPORT, (">>>>EMBX_FindTransport(%s)\n",(name==0?"(NULL)":name)));
    EMBX_DebugOn(EMBX_INFO_TRANSPORT);

    if(!_embx_dvr_ctx.isLockInitialized)
    {
        EMBX_DebugMessage((_driver_uninit_error));
        res = EMBX_DRIVER_NOT_INITIALIZED;
        goto exit;
    }

    if((name == 0) || (tpinfo == 0))
    {
        res = EMBX_INVALID_ARGUMENT;
        goto exit;
    }


    EMBX_OS_MUTEX_TAKE(&_embx_dvr_ctx.lock);

    if(_embx_dvr_ctx.state != EMBX_DVR_INITIALIZED)
    {
        EMBX_DebugMessage((_driver_uninit_error));
        res = EMBX_DRIVER_NOT_INITIALIZED;
    }
    else
    {
    EMBX_TransportList_t *tpl;

        tpl = EMBX_find_transport_entry(name);
        if(tpl != 0)
        {
            EMBX_Info(EMBX_INFO_TRANSPORT,("Found transport\n"));

            *tpinfo = tpl->transport->transportInfo;
            res = EMBX_SUCCESS;
        }
        else
        {
            EMBX_Info(EMBX_INFO_TRANSPORT,("Could not find transport\n"));
            res = EMBX_INVALID_TRANSPORT;
        }
    }

    EMBX_OS_MUTEX_RELEASE(&_embx_dvr_ctx.lock);


exit:
    EMBX_DebugOff(EMBX_INFO_TRANSPORT);
    EMBX_Info(EMBX_INFO_TRANSPORT, ("<<<<EMBX_FindTransport(%s) = %d\n",(name==0?"(NULL)":name), res));

    return res;
}
Esempio n. 15
0
EMBX_EVENT EMBX_OS_EventCreate(void)
{
    EMBX_EVENT ev = NULL;

    /* This is not multithread safe - perhaps use an atomic test&set ? */
    if (!cacheInitialised)
    {
        cacheInitialised = 1;
	(void) EMBX_OS_MUTEX_INIT(&cacheLock);
    }
    
    EMBX_OS_MUTEX_TAKE(&cacheLock);
    
    if ((ev = cacheHead) != NULL)
    {
        cacheHead = cacheHead->next;

	/* Mark desc as being in use */
	ev->next = (EMBX_EVENT) EMBX_HANDLE_VALID;

	EMBX_OS_MUTEX_RELEASE(&cacheLock);
    }
    else
    {
        EMBX_OS_MUTEX_RELEASE(&cacheLock);
      
	/* Dynamically allocate a new cache container
	 * and initialise the event inside it
	 */
	ev = EMBX_OS_MemAlloc(sizeof(*ev));
	
	if (ev)
	{
	    /* Mark desc as being in use */
	    ev->next = (EMBX_EVENT) EMBX_HANDLE_VALID;

	    ev->event = semaphore_create_fifo(0);
	}
    }
    
    return ev;
}
Esempio n. 16
0
EMBX_ERROR EMBX_GetTransportInfo(EMBX_TRANSPORT htp, EMBX_TPINFO *tpinfo)
{
EMBX_ERROR res = EMBX_INVALID_TRANSPORT;

    EMBX_Info(EMBX_INFO_TRANSPORT, (">>>>EMBX_GetTransportInfo(htp=0x%08lx)\n",(unsigned long)htp));
    EMBX_DebugOn(EMBX_INFO_TRANSPORT);

    if(!_embx_dvr_ctx.isLockInitialized)
    {
        EMBX_DebugMessage((_driver_uninit_error));
        goto exit;
    }

    if(tpinfo == 0)
    {
        res = EMBX_INVALID_ARGUMENT;
        goto exit;
    }

    if(!EMBX_HANDLE_ISTYPEOF(htp, EMBX_HANDLE_TYPE_TRANSPORT))
    {
        goto exit;
    }


    EMBX_OS_MUTEX_TAKE(&_embx_dvr_ctx.lock);

    if(_embx_dvr_ctx.state != EMBX_DVR_INITIALIZED)
    {
        EMBX_DebugMessage((_driver_uninit_error));
    }
    else
    {
    EMBX_TransportHandle_t *tph;

        tph = (EMBX_TransportHandle_t *)EMBX_HANDLE_GETOBJ(&_embx_handle_manager, htp);
        if( (tph != 0) && (tph->state == EMBX_HANDLE_VALID) )
        {
            *tpinfo = tph->transport->transportInfo;
            EMBX_Info(EMBX_INFO_TRANSPORT, ("Returning transport '%s'\n",tpinfo->name));

            res = EMBX_SUCCESS;
        }
    }

    EMBX_OS_MUTEX_RELEASE(&_embx_dvr_ctx.lock);


exit:
    EMBX_DebugOff(EMBX_INFO_TRANSPORT);
    EMBX_Info(EMBX_INFO_TRANSPORT, ("<<<<EMBX_GetTransportInfo(htp=0x%08lx) = %d\n",(unsigned long)htp, res));

    return res;
}
Esempio n. 17
0
MME_ERROR MME_HostDeregisterTransport(const char* name)
#endif
{
	EMBX_ERROR err;
	TransportInfo_t *tpInfo, **prev;
	MME_ERROR res;

#ifndef MME_LEAN_AND_MEAN
        if (manager == NULL) {
		MME_Info(MME_INFO_MANAGER, (DEBUG_ERROR_STR "MME not initialized\n"));
                return MME_DRIVER_NOT_INITIALIZED;      /* the manager must exist */
        }

	if (name == NULL) {
		MME_Info(MME_INFO_MANAGER, (DEBUG_ERROR_STR "Transport name NULL\n"));
		return MME_INVALID_ARGUMENT;
	}
#endif

	EMBX_OS_MUTEX_TAKE(&manager->monitorMutex);	

	MME_Info(MME_INFO_MANAGER, (DEBUG_NOTIFY_STR "Looking for transport %s\n", name));
	/* search the transport list for the appropriate transport */
	for (tpInfo = *(prev = &manager->transportList); tpInfo; tpInfo = *(prev = &tpInfo->next)) {
		EMBX_TPINFO embxTpInfo;

		err = EMBX_GetTransportInfo(tpInfo->handle, &embxTpInfo);
		MME_Assert(EMBX_SUCCESS == err);

		if (0 == strcmp(name, embxTpInfo.name)) {
			break;
		}
	}

	if (!tpInfo) {
		MME_Info(MME_INFO_MANAGER, (DEBUG_ERROR_STR "Transport not found\n"));
		res = MME_INVALID_ARGUMENT;
	} else if (0 != tpInfo->referenceCount) {
		MME_Info(MME_INFO_MANAGER, (DEBUG_ERROR_STR "Handles still open\n"));
		res = MME_HANDLES_STILL_OPEN;
	} else {
		res = MME_SUCCESS;
		
		MME_Info(MME_INFO_MANAGER, (DEBUG_NOTIFY_STR "Removing transport\n"));
		/* remove the transport information from the list and cleanup */
		*prev = tpInfo->next;
		destroyTransportInfo(tpInfo);
	}

	EMBX_OS_MUTEX_RELEASE(&manager->monitorMutex);
	MME_Info(MME_INFO_MANAGER, (DEBUG_NOTIFY_STR "<<<< (%d)\n", res));
	return res;
}
Esempio n. 18
0
/* Peek does not dequeue the entry. */
MME_ERROR MME_MessageQueue_Peek(MMEMessageQueue * msgQ, void **message)
{
	MME_Info(MME_INFO_QUEUE, (">>>MME_MessageQueue_Peek(0x%08x, ...)\n", (unsigned) msgQ));

	sortMessageQueue(msgQ);
	EMBX_OS_MUTEX_TAKE(&msgQ->queueLock);
	if (NULL == msgQ->sorted_front) {
		*message = NULL;
		MME_Info(MME_INFO_QUEUE, ("<<<MME_MessageQueue_Peek(..., 0) = MME_INVALID_HANDLE\n"));
		EMBX_OS_MUTEX_RELEASE(&msgQ->queueLock);
		return MME_INVALID_HANDLE;
	}

	*message = msgQ->sorted_front->message;

	EMBX_OS_MUTEX_RELEASE(&msgQ->queueLock);

	MME_Info(MME_INFO_QUEUE, ("<<<MME_MessageQueue_Peek(..., 0x%08x) = MME_SUCCESS\n",
				  (unsigned) *message));
	return MME_SUCCESS;
}
Esempio n. 19
0
static MME_ERROR RemoteTransformer_ReleaseCommandSlot(Transformer_t* transformer, CommandSlot_t* slot)
{
	RemoteTransformer_t *remoteTransformer = (RemoteTransformer_t *) transformer;
	EMBX_OS_MUTEX_TAKE(&remoteTransformer->commandSlotLock);

	remoteTransformer->numCommandSlots--;
	slot->status = MME_COMMAND_COMPLETED_EVT;

	EMBX_OS_MUTEX_RELEASE(&remoteTransformer->commandSlotLock);

	return MME_SUCCESS;
}
Esempio n. 20
0
EMBX_ERROR EMBX_GetFirstTransport(EMBX_TPINFO *tpinfo)
{
EMBX_ERROR res;

    EMBX_Info(EMBX_INFO_TRANSPORT, (">>>>EMBX_GetFirstTransport\n"));
    EMBX_DebugOn(EMBX_INFO_TRANSPORT);

    if(!_embx_dvr_ctx.isLockInitialized)
    {
        EMBX_DebugMessage((_driver_uninit_error));
        res = EMBX_DRIVER_NOT_INITIALIZED;
        goto exit;
    }

    if(tpinfo == 0)
    {
        res = EMBX_INVALID_ARGUMENT;
        goto exit;
    }


    EMBX_OS_MUTEX_TAKE(&_embx_dvr_ctx.lock);

    if(_embx_dvr_ctx.state != EMBX_DVR_INITIALIZED)
    {
        EMBX_DebugMessage((_driver_uninit_error));
        res = EMBX_DRIVER_NOT_INITIALIZED;
    }
    else
    {
        if(_embx_dvr_ctx.transports == 0)
        {
            res = EMBX_INVALID_STATUS;
        }
        else
        {
            *tpinfo = _embx_dvr_ctx.transports->transport->transportInfo;
            EMBX_Info(EMBX_INFO_TRANSPORT, ("Returning transport '%s'\n",tpinfo->name));

            res = EMBX_SUCCESS;
        }
    }

    EMBX_OS_MUTEX_RELEASE(&_embx_dvr_ctx.lock);


exit:
    EMBX_DebugOff(EMBX_INFO_TRANSPORT);
    EMBX_Info(EMBX_INFO_TRANSPORT, ("<<<<EMBX_GetFirstTransport = %d\n", res));

    return res;
}
Esempio n. 21
0
void EMBX_OS_EventDelete(EMBX_EVENT ev)
{
    EMBX_OS_MUTEX_TAKE(&cacheLock);

    EMBX_Assert(ev);
    EMBX_Assert(ev->next == (EMBX_EVENT) EMBX_HANDLE_VALID);

    EMBX_Assert(semaphore_value(ev->event) == 0);
    
    ev->next = cacheHead;
    cacheHead = ev;
    
    EMBX_OS_MUTEX_RELEASE(&cacheLock);
}
Esempio n. 22
0
static void sortMessageQueue(MMEMessageQueue *msgQ)
{
	MMEMessageQueueEntry *entry;

	/* take the unsorted list and merge it with the sorted list.
	 * this code is optimized for FIFO operations and the time
	 * comparisions allow time to wrap. they do not directly 
	 * compare values but subtract with overflow wrap and compare
	 * against 0. note ANSI C only guarantees overflow wrap for 
	 * unsigned values (which is why the priority member is unsigned).
	 */

	EMBX_OS_MUTEX_TAKE(&msgQ->queueLock);
	entry = msgQ->unsorted_front;
	while (entry) {
		msgQ->unsorted_front = entry->next;

		if (NULL == msgQ->sorted_front) {
			/* empty list short circuit */
			entry->next = NULL;
			msgQ->sorted_front = entry;
			msgQ->sorted_back = entry;
		} else if (0 >= (int) (msgQ->sorted_back->priority - entry->priority)) {
			/* FIFO ordered queue short circuit */
			entry->next = NULL;
			msgQ->sorted_back->next = entry;
			msgQ->sorted_back = entry;
		} else {
			/* search the queue until we find a entry with a (strictly) more
			 * distant due date
			 */
			MMEMessageQueueEntry **prev, *cur;

			/* search the queue until we find our insertion point. we know
			 * we cannot run off the end otherwise we would have taken one
			 * of the short circuits above.
			 */
			for (prev = &(msgQ->sorted_front), cur = *prev;
			     MME_Assert(cur), 0 >= (int) (cur->priority - entry->priority);
			     prev = &(cur->next), cur = *prev) {} 

			entry->next = cur;
			*prev = entry;
			MME_Assert(*prev != msgQ->sorted_back);
		}

		entry = msgQ->unsorted_front;
	}
	EMBX_OS_MUTEX_RELEASE(&msgQ->queueLock);
}
Esempio n. 23
0
MME_ERROR MME_RegisterTransformer(const char *name,
				  MME_AbortCommand_t abortFunc,
				  MME_GetTransformerCapability_t getTransformerCapabilityFunc,
				  MME_InitTransformer_t initTransformerFunc,
				  MME_ProcessCommand_t processCommandFunc,
				  MME_TermTransformer_t termTransformerFunc)
#endif
{
	MMEReceiverFactory* factory;

#ifndef MME_LEAN_AND_MEAN
	if (NULL == manager) {
		return MME_DRIVER_NOT_INITIALIZED;
	}

	if (NULL == name) {
		return MME_INVALID_ARGUMENT;
	}

	/* iterate over the (singly linked) factory list looking for duplicates */
	for (factory = manager->factoryList; NULL != factory; factory = factory->next) {
		if (0 == strcmp(factory->transformerType, name)) {
			return MME_INVALID_ARGUMENT;
		}
	}
#endif

	factory = malloc(sizeof(MMEReceiverFactory) + strlen(name) + 1);
	if (NULL == factory) {
		return MME_NOMEM;
	}

	factory->transformerType              = (const char *) (factory + 1);
	strcpy((void *) factory->transformerType, name);
	factory->abortFunc                    = abortFunc;
	factory->getTransformerCapabilityFunc = getTransformerCapabilityFunc;
	factory->initTransformerFunc          = initTransformerFunc;
	factory->processCommandFunc           = processCommandFunc;
	factory->termTransformerFunc          = termTransformerFunc;
#ifdef EMBX_RECEIVE_CALLBACK
	factory->createThread                 = createThread;
#endif /* EMBX_RECEIVE_CALLBACK */

	EMBX_OS_MUTEX_TAKE(&(manager->factoryListMutex));
	factory->next = manager->factoryList;
	manager->factoryList = factory;
	EMBX_OS_MUTEX_RELEASE(&(manager->factoryListMutex));

	return MME_SUCCESS;
}
Esempio n. 24
0
MME_ERROR MME_MessageQueue_Enqueue(MMEMessageQueue * msgQ, void *message, unsigned int priority)
{
	MMEMessageQueueEntry *entry;

	MME_Info(MME_INFO_QUEUE, (">>>MME_MessageQueue_Enqueue(0x%08x, 0x%08x)\n", 
	                          (unsigned) msgQ, (unsigned) message));

	EMBX_OS_MUTEX_TAKE(&msgQ->queueLock);

	/* fetch a free linkage structure from the free list */
	entry = msgQ->free_list;
	if (NULL == entry) {
		EMBX_OS_MUTEX_RELEASE(&msgQ->queueLock);
		MME_Info(MME_INFO_QUEUE, ("<<<MME_MessageQueue_Enqueue = MME_NOMEM\n"));
		return MME_NOMEM;
	}
	msgQ->free_list = entry->next;

	/* fill in the linkage structure */
	entry->next = NULL;
	entry->priority = priority;
	entry->message = message;

	/* add it to the unsorted FIFO queue. we use a FIFO queue in order to
	 * exploit the FIFO optimizations in SortMMEMessageQueue.
	 */
	if (NULL == msgQ->unsorted_front) {
		msgQ->unsorted_front = entry;
	} else {
		msgQ->unsorted_back->next = entry;
	}
	msgQ->unsorted_back = entry;

	EMBX_OS_MUTEX_RELEASE(&msgQ->queueLock);
	MME_Info(MME_INFO_QUEUE, ("<<<MME_MessageQueue_Enqueue = MME_SUCCESS\n"));
	return MME_SUCCESS;
}
Esempio n. 25
0
/*
 * Transport method to close an open handle
 */
static EMBX_ERROR closeHandle (EMBX_Transport_t       *tp,
                               EMBX_TransportHandle_t *tph)
{
    EMBXSHM_Transport_t        *tpshm = (EMBXSHM_Transport_t *)tp;
    EMBX_EventState_t          *es, *next;

    EMBX_Info (EMBX_INFO_TRANSPORT, (">>>closeHandle()\n"));
    EMBX_Assert (tpshm);
    EMBX_Assert (tph);

    EMBX_OS_MUTEX_TAKE (&tpshm->connectionListMutex);

    /*
     * Unblock processes waiting for a connection through the closing handle
     */
    for (es = tpshm->connectionRequests; es; es = next)
    {
	EMBXSHM_ConnectBlockState_t *cbs = es->data; /* match with CBS IN DATA */

        next = es->next;

        if (cbs->requestingHandle == tph)
        {
	    EMBX_EventListRemove(&tpshm->connectionRequests, es);
	    EMBX_OS_MemFree (cbs);

            es->result = EMBX_TRANSPORT_CLOSED;
            EMBX_OS_EVENT_POST (&es->event);
        }
    }

    EMBX_OS_MUTEX_RELEASE (&tpshm->connectionListMutex);

    /*
     * Make key handle structures invalid to help catch use after close
     */
    tph->state     = EMBX_HANDLE_CLOSED;
    tph->transport = 0;

    EMBX_OS_MemFree (tph);

    EMBX_OS_MODULE_UNREF();

    EMBX_Info (EMBX_INFO_TRANSPORT, ("<<<closeHandle = EMBX_SUCCESS\n"));
    return EMBX_SUCCESS;
}
Esempio n. 26
0
static void unblockWaitors(RemoteTransformer_t* remoteTransformer, MME_Event_t event, CommandSlot_t* command) 
{
	HostManager_t* manager = MMEGetManager();
	
	/* Lock whilst this thread does event notification */
	MME_Assert(manager);

	EMBX_OS_MUTEX_TAKE(&manager->eventLock);

	manager->eventTransformer = remoteTransformer;
	manager->eventCommand     = command;
	manager->eventCommandType = event;

	EMBX_OS_EVENT_POST(command->waitor);

	EMBX_OS_EVENT_WAIT(&manager->waitorDone);

	EMBX_OS_MUTEX_RELEASE(&manager->eventLock);
}
Esempio n. 27
0
EMBX_ERROR EMBX_CloseTransport(EMBX_TRANSPORT htp)
{
EMBX_ERROR res = EMBX_INVALID_TRANSPORT;

    EMBX_Info(EMBX_INFO_TRANSPORT, (">>>>EMBX_CloseTransport(htp=0x%08lx)\n",(unsigned long)htp));
    EMBX_DebugOn(EMBX_INFO_TRANSPORT);

    if(!_embx_dvr_ctx.isLockInitialized)
    {
        EMBX_DebugMessage((_driver_uninit_error));
        goto exit;
    }

    if(!EMBX_HANDLE_ISTYPEOF(htp, EMBX_HANDLE_TYPE_TRANSPORT))
    {
        goto exit;
    }


    EMBX_OS_MUTEX_TAKE(&_embx_dvr_ctx.lock);

    if(_embx_dvr_ctx.state != EMBX_DVR_INITIALIZED &&
       _embx_dvr_ctx.state != EMBX_DVR_IN_SHUTDOWN )
    {
        EMBX_DebugMessage((_driver_uninit_error));
    }
    else
    {
        res = do_close_transport(htp);
    }

    EMBX_OS_MUTEX_RELEASE(&_embx_dvr_ctx.lock);


exit:
    EMBX_DebugOff(EMBX_INFO_TRANSPORT);
    EMBX_Info(EMBX_INFO_TRANSPORT, ("<<<<EMBX_CloseTransport(htp=0x%08lx) = %d\n",(unsigned long)htp, res));

    return res;
}
Esempio n. 28
0
MME_ERROR MME_MessageQueue_RemoveByValue(MMEMessageQueue *msgQ, void *message)
{
	MMEMessageQueueEntry **prev, *cur;

	sortMessageQueue(msgQ);

	EMBX_OS_MUTEX_TAKE(&msgQ->queueLock);
	for (cur = *(prev = &msgQ->sorted_front); cur; cur = *(prev = &cur->next)) {
		if (cur->message == message) {
			/* dequeue the message */
			*prev = cur->next;

			/* push it onto the free list */
			cur->next = msgQ->free_list;
			msgQ->free_list = cur;
			break;
		}
	}

	EMBX_OS_MUTEX_RELEASE(&msgQ->queueLock);
	return (cur ? MME_SUCCESS : MME_INVALID_ARGUMENT);
}
Esempio n. 29
0
MME_ERROR MME_IsStillAlive(MME_TransformerHandle_t handle, MME_UINT* alive)
{
	Transformer_t *transformer;
	MME_ERROR result;

#ifndef MME_LEAN_AND_MEAN
        if (manager == NULL) {
                return MME_DRIVER_NOT_INITIALIZED;      /* the manager must exist */
        }
#endif

	EMBX_OS_MUTEX_TAKE(&manager->monitorMutex);
	result = findTransformerInstance(handle, &transformer);
	EMBX_OS_MUTEX_RELEASE(&manager->monitorMutex);

	if (result != MME_SUCCESS) {
		/* cannot find transformer for this handle */
		return MME_INVALID_HANDLE;
	}

	result = transformer->vtable->isStillAlive(transformer, alive);

	return result;
}
Esempio n. 30
0
/*
 * Remote port method to perform an object update
 */
static EMBX_ERROR updateObject (EMBX_RemotePortHandle_t *ph,
                                EMBX_HANDLE              handle,
                                EMBX_UINT                offset,
                                EMBX_UINT                size)
{
    EMBXSHM_RemotePortHandle_t *remotePortHandle = (EMBXSHM_RemotePortHandle_t *)ph;
    EMBXSHM_Transport_t        *tpshm;
    EMBXSHM_Object_t           *obj;
    EMBX_ERROR                  err = EMBX_SUCCESS;

    EMBX_Info(EMBX_INFO_REMOTEPORT, (">>>updateObject(0x%08x, ...)\n", (unsigned) ph));

    EMBX_Assert (ph);
    EMBX_Assert (ph->transportHandle);

    tpshm = (EMBXSHM_Transport_t *)ph->transportHandle->transport;

    EMBX_Assert (tpshm);

    /*
     * Do some up front sanity checks
     */
    obj = EMBXSHM_findObject (tpshm, handle);

    if ((obj == 0) || ((offset+size) > obj->size))
    {
	EMBX_Info(EMBX_INFO_REMOTEPORT, ("<<<updateObject = EMBX_INVALID_ARGUMENT\n"));
        return EMBX_INVALID_ARGUMENT;
    }

    EMBX_Assert(EMBXSHM_ALIGNED_TO_CACHE_LINE(obj));

    /*
     * See if this is a local or remote send/update
     */
    if (remotePortHandle->destinationCPU == tpshm->cpuID)
    {
        /*
         * A local update, so we're all done
         */
	EMBX_Info(EMBX_INFO_REMOTEPORT, ("<<<updateObject = EMBX_SUCCESS\n"));
        return EMBX_SUCCESS;
    }
    else
    {
        /*
         * This is an object update to a port owned by another CPU.
         * We may need to copy shadowed data around, and possibly
         * send an update message to the other guy.
         */
        EMBXSHM_PipeElement_t element;

	EMBX_VOID *dst = BUS_TO_LOCAL (obj->sharedData, tpshm->pointerWarp);

	/*
	 * Update the shared copy of this object is it is shadowed from a master
	 * copy on this CPU.
	 */
	if (obj->owningCPU == tpshm->cpuID && obj->shadow)
	{
	    memcpy ((void*)((size_t)dst+offset), (void*)((size_t)obj->localData+offset), size);
	}

	/*
	 * Ensure the object data is not held in our own cache.
	 */
	if (obj->mode == EMBX_INCOHERENT_MEMORY)
	  EMBX_OS_FlushCache((char *)dst+offset, size);

	/*
	 * Under the protection of the accessMutex, check the port state
	 * is still OK. If it is, then the local port we're pointing to
	 * is still OK too. By the time the message gets to the other
	 * side (could be another CPU), then the local port could could
	 * have been closed out - he will drop it on the floor.
	 */
	EMBX_OS_MUTEX_TAKE (&remotePortHandle->accessMutex);

	if (remotePortHandle->port.state != EMBX_HANDLE_VALID)
	{
	    EMBX_OS_MUTEX_RELEASE (&remotePortHandle->accessMutex);
	    return EMBX_INVALID_STATUS;
	}

	EMBX_Assert (remotePortHandle->destination.sharedPort->owningCPU == 
	             remotePortHandle->destinationCPU);

	/*
	 * Now inform the partner CPU that the object has been updated.
	 */
	element.control              = EMBXSHM_PIPE_CTRL_OBJ_UPDATE;
	element.data.msg_send.port   = (EMBXSHM_LocalPortShared_t*) LOCAL_TO_BUS (
		remotePortHandle->destination.sharedPort, tpshm->pointerWarp);
	element.data.obj_send.handle = handle;
	element.data.obj_send.data   = obj->sharedData;
	element.data.obj_send.offset = offset;
	element.data.obj_send.size   = size;

	err = EMBXSHM_enqueuePipeElement (tpshm, remotePortHandle->destinationCPU, &element);

	EMBX_OS_MUTEX_RELEASE (&remotePortHandle->accessMutex);
    }

    EMBX_Info(EMBX_INFO_REMOTEPORT, ("<<<sendObject = %d\n", err));
    return err;
}