diff --git a/src/cas/os/vxWorks/caServerOS.cc b/src/cas/os/vxWorks/caServerOS.cc new file mode 100644 index 000000000..b8394802d --- /dev/null +++ b/src/cas/os/vxWorks/caServerOS.cc @@ -0,0 +1,124 @@ +/* + * + * caServerOS.c + * $Id$ + * + * + * $Log$ + * Revision 1.1.1.1 1996/06/20 00:28:06 jhill + * ca server installation + * + * + */ + +#include +#include + +// +// CA server +// +#include + +// +// aServerOS::operator -> () +// +inline caServerI * caServerOS::operator -> () +{ + return &this->cas; +} + +// +// casBeaconTimer::expire() +// +void casBeaconTimer::expire() +{ + os->sendBeacon (); +} + +// +// casBeaconTimer::again() +// +osiBool casBeaconTimer::again() +{ + return osiTrue; +} + +// +// casBeaconTimer::delay() +// +const osiTime casBeaconTimer::delay() +{ + return os->getBeaconPeriod(); +} + + +// +// caServerOS::init() +// +caStatus caServerOS::init() +{ + this->pBTmr = new casBeaconTimer((*this)->getBeaconPeriod(), *this); + if (!this->pBTmr) { + ca_printf("CAS: Unable to start server beacon\n"); + return S_cas_noMemory; + } + + // + // WRS still passes pointers in ints + // + assert (sizeof(int)==sizeof(&this->cas)); + + this->tid = taskSpawn ( + REQ_SRVR_NAME, + REQ_SRVR_PRI, + REQ_SRVR_OPT, + REQ_SRVR_STACK, + (FUNCPTR) caServerEntry, // get your act together WRS + (int) &this->cas, // get your act together WRS + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL); + if (this->tid==ERROR) { + return S_cas_noMemory; + } + + return S_cas_success; +} + + +// +// caServerOS::~caServerOS() +// +caServerOS::~caServerOS() +{ + if (this->pBTmr) { + delete this->pBTmr; + } + + if (taskIdVerify(this->tid)==OK) + { + taskDelete(this->tid); + } +} + + +// +// caServer() +// +void caServer(caServerI *pCAS) +{ + // + // forever + // + while (TRUE) { + pCAS->connectCB(); + printf("process timer q here?\n"); + } +} + diff --git a/src/cas/os/vxWorks/casClientOS.h b/src/cas/os/vxWorks/casClientOS.h new file mode 100644 index 000000000..ec99fcc90 --- /dev/null +++ b/src/cas/os/vxWorks/casClientOS.h @@ -0,0 +1,77 @@ + +class casStreamEvWakeup; + +// +// casStreamOS +// +class casStreamOS : public casStrmClient { + friend int casStrmServer (casStreamOS *); + friend int casStrmEvent (casStreamOS *); +public: + casStreamOS(caServerI &, casMsgIO &); + caStatus init(); + ~casStreamOS(); + + // + // process any incomming messages + // + casProcCond processInput(); + caStatus start(); + + void sendBlockSignal(); + void ioBlockedSignal(); + + void eventSignal(); + void eventFlush(); + + void show(unsigned level); +private: + SEM_ID eventSignalSem; + int clientTId; + int eventTId; +}; + +// +// vxWorks task entry +// +int casStrmServer (casStreamOS *); +int casStrmEvent (casStreamOS *); + +class casDGEvWakeup; + +// +// casDGOS +// +class casDGOS : public casDGClient { + friend int casDGServer (casDGOS *); + friend int casDGEvent (casDGOS *); +public: + casDGOS(caServerI &cas); + caStatus init(); + ~casDGOS(); + + // + // process any incomming messages + // + casProcCond processInput(); + caStatus start(); + + void sendBlockSignal() {} + + void eventSignal(); + void eventFlush(); + + void show(unsigned level); +private: + SEM_ID eventSignalSem; + int clientTId; + int eventTId; +}; + +// +// vxWorks task entry +// +int casDGServer (casDGOS *); +int casDGEvent (casDGOS *); + + diff --git a/src/cas/os/vxWorks/casDGOS.cc b/src/cas/os/vxWorks/casDGOS.cc new file mode 100644 index 000000000..d5e5aa595 --- /dev/null +++ b/src/cas/os/vxWorks/casDGOS.cc @@ -0,0 +1,211 @@ + +/* + * + * casDGOS.c + * $Id$ + * + * + * $Log$ + * Revision 1.1.1.1 1996/06/20 00:28:06 jhill + * ca server installation + * + * + */ + +// +// CA server +// +#include // vxWorks + +#include +#include // casClient inline func +#include // EPICS task priorities + +// +// casDGOS::eventSignal() +// +void casDGOS::eventSignal() +{ + STATUS st; + + st = semGive(this->eventSignalSem); + assert (st==OK); +} + +// +// casDGOS::eventFlush() +// +void casDGOS::eventFlush() +{ + this->flush(); +} + + +// +// casDGOS::casDGOS() +// +casDGOS::casDGOS(caServerI &cas) : + eventSignalSem(NULL), + casDGClient(cas), + clientTId(ERROR), + eventTId(ERROR) +{ +} + +// +// casDGOS::init() +// +caStatus casDGOS::init() +{ + caStatus status; + + this->eventSignalSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); + if (this->eventSignalSem == NULL) { + return S_cas_noMemory; + } + + // + // init the base classes + // + status = this->casDGClient::init(); + + return status; +} + + +// +// casDGOS::~casDGOS() +// +casDGOS::~casDGOS() +{ + if (taskIdVerify(this->clientTId)==OK) { + taskDelete(this->clientTId); + } + if (taskIdVerify(this->eventTId)==OK) { + taskDelete(this->eventTId); + } + if (this->eventSignalSem) { + semDelete(this->eventSignalSem); + } +} + +// +// casDGOS::show() +// +void casDGOS::show(unsigned level) +{ + this->casDGClient::show(level); + printf ("casDGOS at %x\n", (unsigned) this); + if (taskIdVerify(this->clientTId) == OK) { + taskShow(this->clientTId, level); + } + if (taskIdVerify(this->eventTId) == OK) { + taskShow(this->eventTId, level); + } + if (this->eventSignalSem) { + semShow(this->eventSignalSem, level); + } +} + + +/* + * casClientStart () + */ +caStatus casDGOS::start() +{ + // + // no (void *) vxWorks task arg + // + assert (sizeof(int) >= sizeof(this)); + + this->clientTId = taskSpawn( + CAST_SRVR_NAME, + CAST_SRVR_PRI, + CAST_SRVR_OPT, + CAST_SRVR_STACK, + (FUNCPTR) casDGServer, // get your act together wrs + (int) this, // get your act together wrs + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL); + if (this->clientTId==ERROR) { + return S_cas_noMemory; + } + this->eventTId = taskSpawn( + CA_EVENT_NAME, + CA_CLIENT_PRI, + CA_CLIENT_OPT, + CAST_SRVR_STACK, + (FUNCPTR) casDGEvent, // get your act together wrs + (int) this, // get your act together wrs + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL); + if (this->eventTId==ERROR) { + return S_cas_noMemory; + } + return S_cas_success; +} + + +/* + * casDGOS::processInput () + * - a noop + */ +casProcCond casDGOS::processInput () +{ + return casProcOk; +} + +// +// casDGServer() +// +int casDGServer (casDGOS *pDGOS) +{ + caStatus status; + + // + // block for the next DG until the connection closes + // + while (TRUE) { + status = pDGOS->processInput(); + if (status) { + errMessage(status, "casDGServer (casDGOS *pDGOS)"); + } + } +} + +// +// casDGEvent() +// +int casDGEvent (casDGOS *pDGOS) +{ + STATUS status; + casProcCond cond; + + // + // Wait for event queue entry + // + while (TRUE) { + status = semTake(pDGOS->eventSignalSem, WAIT_FOREVER); + assert (status!=OK); + + cond = pDGOS->casEventSys::process(); + if (cond != casProcOk) { + printf("DG event sys process failed\n"); + } + } +} + diff --git a/src/cas/os/vxWorks/casOSD.h b/src/cas/os/vxWorks/casOSD.h new file mode 100644 index 000000000..280cadb26 --- /dev/null +++ b/src/cas/os/vxWorks/casOSD.h @@ -0,0 +1,92 @@ +// +// $Id$ +// +// casOSD.h - Channel Access Server OS Dependent for posix +// +// +// Some BSD calls have crept in here +// +// $Log$ +// Revision 1.1.1.1 1996/06/20 00:28:06 jhill +// ca server installation +// +// + +#ifndef includeCASOSDH +#define includeCASOSDH + + +#include +#include + + +extern "C" { +// +// for htons() etc +// +# include +# include +} // extern "C" + +#include +#include + +class caServerI; + +class caServerOS; + +// +// casBeaconTimer +// +class casBeaconTimer : public osiTimer { +public: + casBeaconTimer (const osiTime &delay, caServerOS &osIn) : + os (osIn), osiTimer(delay) {} + void expire(); + const osiTime delay(); + osiBool again(); + const char *name() + { + return "casBeaconTimer"; + } +private: + caServerOS &os; + int taskId; +}; + +class casServerReg; + +class caServerOS; + +// +// vxWorks task entry +// +int caServerEntry(caServerI *pCAS); + +// +// caServerOS +// +class caServerOS { + friend class casServerReg; + friend int caServerEntry(caServerOS *pOS); +public: + caServerOS (caServerI &casIn) : + cas (casIn), pBTmr (NULL), tid(ERROR) {} + caStatus init (); + ~caServerOS (); + + //caStatus start (); + + inline caServerI * operator -> (); + + //int getFD(); + +private: + caServerI &cas; + casBeaconTimer *pBTmr; + int tid; +}; + +// no additions below this line +#endif // includeCASOSDH + diff --git a/src/cas/os/vxWorks/casStreamOS.cc b/src/cas/os/vxWorks/casStreamOS.cc new file mode 100644 index 000000000..cd5adb184 --- /dev/null +++ b/src/cas/os/vxWorks/casStreamOS.cc @@ -0,0 +1,280 @@ +// +// casStreamOS.cc +// $Id$ +// +// +// $Log$ +// Revision 1.1.1.1 1996/06/20 00:28:06 jhill +// ca server installation +// +// +// + +// +// CA server +// +#include +#include // casClient inline func +#include // EPICS task priorities + + +// +// casStreamOS::ioBlockedSignal() +// +void casStreamOS::ioBlockedSignal() +{ + printf("in casStreamOS::ioBlockedSignal()\n"); +} + +// +// casStreamOS::eventSignal() +// +void casStreamOS::eventSignal() +{ + STATUS st; + + st = semGive(this->eventSignalSem); + assert (st==OK); +} + +// +// casStreamOS::eventFlush() +// +void casStreamOS::eventFlush() +{ + this->flush(); +} + + +// +// casStreamOS::casStreamOS() +// +casStreamOS::casStreamOS(caServerI &cas, casMsgIO &ioIn) : + casStrmClient(cas, ioIn), + eventSignalSem(NULL), + clientTId(NULL), + eventTId(NULL) +{ +} + +// +// casStreamOS::init() +// +caStatus casStreamOS::init() +{ + caStatus status; + + this->eventSignalSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); + if (this->eventSignalSem == NULL) { + return S_cas_noMemory; + } + + // + // init the base classes + // + status = this->casStrmClient::init(); + if (status) { + return status; + } + + return S_cas_success; +} + + +// +// casStreamOS::~casStreamOS() +// +casStreamOS::~casStreamOS() +{ + // + // attempt to flush out any remaining messages + // + this->flush(); + + if (taskIdVerify(this->clientTId)==OK && + this->clientTId != taskIdSelf()) { + taskDelete(this->clientTId); + } + if (taskIdVerify(this->eventTId)==OK && + this->eventTId != taskIdSelf()) { + taskDelete(this->eventTId); + } + if (this->eventSignalSem) { + semDelete(this->eventSignalSem); + } +} + +// +// casStreamOS::show() +// +void casStreamOS::show(unsigned level) +{ + this->casStrmClient::show(level); + printf("casStreamOS at %x\n", (unsigned) this); + if (taskIdVerify(this->clientTId)==OK) { + taskShow(this->clientTId, level); + } + if (taskIdVerify(this->eventTId)==OK) { + taskShow(this->eventTId, level); + } + if (this->eventSignalSem) { + semShow(this->eventSignalSem, level); + } +} + + +// +// casClientStart () +// +caStatus casStreamOS::start() +{ + // + // no (void *) vxWorks task arg + // + assert (sizeof(int) >= sizeof(this)); + + this->clientTId = taskSpawn( + CA_CLIENT_NAME, + CA_CLIENT_PRI, + CA_CLIENT_OPT, + CA_CLIENT_STACK, + (FUNCPTR) casStrmServer, // get your act together wrs + (int) this, // get your act together wrs + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL); + if (this->clientTId==ERROR) { + return S_cas_noMemory; + } + this->eventTId = taskSpawn( + CA_EVENT_NAME, + CA_CLIENT_PRI, + CA_CLIENT_OPT, + CA_CLIENT_STACK, + (FUNCPTR) casStrmEvent, // get your act together wrs + (int) this, // get your act together wrs + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL); + if (this->eventTId==ERROR) { + return S_cas_noMemory; + } + return S_cas_success; +} + + +// +// casStreamOS::sendBlockSignal() +// +void casStreamOS::sendBlockSignal() +{ + printf("in casStreamOS::sendBlockSignal()\n"); +} + +// +// casStreamOS::processInput() +// +casProcCond casStreamOS::processInput() +{ + caStatus status; + +# ifdef DEBUG + printf( + "Resp bytes to send=%d, Req bytes pending %d\n", + this->outBuf::bytesPresent(), + this->inBuf::bytesPresent()); +# endif + + status = this->processMsg(); + switch (status) { + case S_cas_partialMessage: + case S_cas_ioBlocked: + case S_cas_success: + return casProcOk; + default: + errMessage (status, + "unexpected error processing client's input"); + return casProcDisconnect; + } +} + +// +// casStrmServer() +// +int casStrmServer (casStreamOS *pStrmOS) +{ + casFillCondition fillCond; + casProcCond procCond; + caStatus status; + + // + // block for the next DG until the connection closes + // + while (TRUE) { + // + // copy in new messages + // + fillCond = pStrmOS->fill(); + procCond = pStrmOS->processInput(); + if (fillCond == casFillDisconnect || + procCond == casProcDisconnect) { + delete pStrmOS; + // + // NO CODE HERE + // (see delete above) + // + return OK; + } + else if (pStrmOS->inBuf::full()==aitTrue) { + // + // If there isnt any space then temporarily + // stop calling this routine until problem is resolved + // either by: + // (1) sending or + // (2) a blocked IO op unblocks + // + delete pStrmOS; + // + // NO CODE HERE + // (see delete above) + // + return OK; + } + } + +} + +// +// casStrmEvent() +// +int casStrmEvent(casStreamOS *pStrmOS) +{ + STATUS status; + casProcCond cond; + + // + // Wait for event queue entry + // + while (TRUE) { + status = semTake(pStrmOS->eventSignalSem, WAIT_FOREVER); + assert (status!=OK); + + cond = pStrmOS->casEventSys::process(); + if (cond != casProcOk) { + printf("Stream event sys process failed\n"); + } + } +} + diff --git a/src/cas/os/vxWorks/osiMutex.h b/src/cas/os/vxWorks/osiMutex.h new file mode 100644 index 000000000..f3cd18624 --- /dev/null +++ b/src/cas/os/vxWorks/osiMutex.h @@ -0,0 +1,51 @@ + +// +// osiMutex - OS independent mutex +// (vxWorks version) +// + +#include +#include + +class osiMutex { +public: + osiMutex() + { + mutex = NULL; + } + // + // constructor that returns status + // (since g++ does not have exceptions) + // + int init () + { + this->mutex = semMCreate(SEM_Q_PRIORITY|SEM_INVERSION_SAFE); + if (this->mutex==NULL) + { + return -1; + } + return 0; + } + ~osiMutex() + { + STATUS s; + s = semDelete (this->mutex); + assert (s==OK); + } + void lock() + { + STATUS s; + assert(this->mutex); + s = semTake (this->mutex, WAIT_FOREVER); + assert (s==OK); + } + void unlock() + { + STATUS s; + s = semGive (this->mutex); + assert (s==OK); + } +private: + SEM_ID mutex; +}; +