void deinit_thread(void *param) { EMBX_TRANSPORT tp = (EMBX_TRANSPORT)param; EMBX_ERROR res; EMBX_OS_Delay((unsigned long)param); res = EMBX_Deinit(); if(res != EMBX_SUCCESS) { EMBX_Info(EMBX_TRUE, ("deinit_thread(%ld) failed, res = %s\n", (unsigned long)param, error_strings[res])); return; } }
void send_thread(void *param) { EMBX_PORT port = (EMBX_PORT)param; EMBX_ERROR res; EMBX_VOID *buffer; EMBX_OS_Delay(5000); EMBX_Alloc(tp,BUFFER_SIZE,&buffer); res = EMBX_SendMessage(port,buffer,BUFFER_SIZE); if(res != EMBX_SUCCESS) { EMBX_Info(EMBX_TRUE, ("port_thread failed, res = %s\n",error_strings[res])); return; } }
/* * Transport method to invalidate a transport */ static EMBX_VOID invalidate (EMBX_Transport_t *tp) { EMBXSHM_Transport_t *tpshm = (EMBXSHM_Transport_t *)tp; EMBX_TransportHandleList_t *thandles = tpshm->transport.transportHandles; EMBX_Info (EMBX_INFO_TRANSPORT, (">>>invalidate()\n")); EMBX_Assert (tpshm); /* * Tell the other CPUs we are about to invalidate the transport. */ if (!tpshm->remoteInvalidateFlag) { EMBXSHM_PipeElement_t element; int i; element.control = EMBXSHM_PIPE_CTRL_TRANSPORT_INVALIDATE; for (i=0; i<EMBXSHM_MAX_CPUS; i++) { if (i != tpshm->cpuID && tpshm->participants[i]) { EMBX_ERROR err; /* * We are already part way through the operation so we'll * keep trying to repost until we manage it. */ while (EMBX_SUCCESS != (err = EMBXSHM_enqueuePipeElement (tpshm, i, &element))) { EMBX_Assert (EMBX_NOMEM == err); EMBX_OS_Delay(10); } } } } thandles = tpshm->transport.transportHandles; /* * First of all wake up any pending connection requests */ EMBX_OS_MUTEX_TAKE (&tpshm->connectionListMutex); while (tpshm->connectionRequests) { EMBX_EventState_t *es = EMBX_EventListFront(&tpshm->connectionRequests); EMBX_OS_MemFree(es->data); /* match with CBS IN DATA */ /* * When we post this event we have effectively freed es, it must not be used again */ EMBX_OS_EVENT_POST (&es->event); } EMBX_OS_MUTEX_RELEASE (&tpshm->connectionListMutex); /* * Now go and deal with still open transport handles */ while (thandles) { EMBXSHM_TransportHandle_t *th = (EMBXSHM_TransportHandle_t *)thandles->transportHandle; doInvalidateHandle (th); thandles = thandles->next; } EMBX_Info (EMBX_INFO_TRANSPORT, ("<<<invalidate\n")); }
/* * Transport method to perform closedown of a transport */ static EMBX_ERROR closedown (EMBX_Transport_t *tp, EMBX_EventState_t *ev) { int i; EMBX_ERROR res; EMBXSHM_Transport_t *tpshm = (EMBXSHM_Transport_t *)tp; EMBX_Info (EMBX_INFO_TRANSPORT, (">>>closedown()\n")); EMBX_Assert (tpshm); if (tpshm->tcb) { EMBXSHM_TCB_t *tcb = tpshm->tcb; EMBX_Assert(tcb && EMBXSHM_ALIGNED_TO_CACHE_LINE(tcb)); /* * We have to wait for everyone else in the transport to die off, * before completing closedown. We leave the interrupt handler * in place, so it can service any port close notifications. */ tcb->activeCPUs[tpshm->cpuID].marker = 0; EMBXSHM_WROTE(&tcb->activeCPUs[tpshm->cpuID].marker); while (activeParticipants (tpshm, tcb)) { EMBX_OS_Delay (50); } } /* * It's now safe to kill off our worker threads, these can fail * due to taking an OS signal while waiting for the thread to * signal termination. */ res = EMBXSHM_killThread(tpshm, EMBXSHM_CLOSEPORT_WORKER); if (res != EMBX_SUCCESS) return res; res = EMBXSHM_killThread(tpshm, EMBXSHM_NEWPORT_WORKER); if (res != EMBX_SUCCESS) return res; /* * If we're the master, we need to rip down all the shared memory * stuff. As we are also going to destroy the shared heap manager there * isn't any point in actually releasing the spin locks and shared * tables. So just zero the whole tcb structure for safety. */ if (tpshm->tcb && tpshm->cpuID == tpshm->masterCPU) { memset(tpshm->tcb, 0, sizeof(EMBXSHM_TCB_t)); } EMBXSHM_WROTE(tpshm->tcb); /* * Forget about the cached spinlock pointers */ tpshm->portTableSpinlock = 0; tpshm->portConnectSpinlock = 0; tpshm->objectTableSpinlock = 0; for (i=0; i<EMBXSHM_MAX_CPUS; i++) { tpshm->pipeLocks[i] = 0; } /* * Closedown the heap manager */ EMBXSHM_memoryDeinit (tpshm); /* * Remove our interrupt handler */ tpshm->remove_isr ((void *)tpshm); /* * Destroy sundry mutexes & events */ EMBXSHM_destroyTransportSyncObjects(tpshm); /* * Callback into the factory code to free any allocated memory */ if (tpshm->cleanup_shm_environment) { tpshm->cleanup_shm_environment(tpshm); } /* * Do not free the tpshm structure, this is done at the framework level */ EMBX_Info (EMBX_INFO_TRANSPORT, ("<<<closedown = EMBX_SUCCESS\n")); return EMBX_SUCCESS; }