/*! \fn void Win_QextSerialPort::setStopBits(StopBitsType stopBits) Sets the number of stop bits used by the serial port. Possible values of stopBits are: \verbatim STOP_1 1 stop bit STOP_1_5 1.5 stop bits STOP_2 2 stop bits \endverbatim \note This function is subject to the following restrictions: \par 2 stop bits cannot be used with 5 data bits. \par 1.5 stop bits cannot be used with 6 or more data bits. \par POSIX does not support 1.5 stop bits. */ void Win_QextSerialPort::setStopBits(StopBitsType stopBits) { LOCK_MUTEX(); if (Settings.StopBits!=stopBits) { if ((Settings.DataBits==DATA_5 && stopBits==STOP_2) || (stopBits==STOP_1_5 && Settings.DataBits!=DATA_5)) { } else { Settings.StopBits=stopBits; } } if (isOpen()) { switch (stopBits) { /*one stop bit*/ case STOP_1: Win_CommConfig.dcb.StopBits=ONESTOPBIT; SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); break; /*1.5 stop bits*/ case STOP_1_5: TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: 1.5 stop bit operation is not supported by POSIX."); if (Settings.DataBits!=DATA_5) { TTY_WARNING("Win_QextSerialPort: 1.5 stop bits can only be used with 5 data bits"); } else { Win_CommConfig.dcb.StopBits=ONE5STOPBITS; SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); } break; /*two stop bits*/ case STOP_2: if (Settings.DataBits==DATA_5) { TTY_WARNING("Win_QextSerialPort: 2 stop bits cannot be used with 5 data bits"); } else { Win_CommConfig.dcb.StopBits=TWOSTOPBITS; SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); } break; } } UNLOCK_MUTEX(); }
//suscribe to topic Id. Receive a callback when a message is received ps_result_enum ps_pubsub_class::subscribe(ps_topic_id_t topicId, message_handler_t *msgHandler) { LOCK_MUTEX(pubsubMtx); //find the client for (psClient_t *client : clientList) { if (client->messageHandler == msgHandler) { client->topicList.insert(topicId); //add new subscription if (topicId >= topic_count) { PS_DEBUG("pub: subscribe to topic %i", topicId); } else { PS_DEBUG("pub: subscribe to topic %s", topic_names[topicId]); } UNLOCK_MUTEX(pubsubMtx); return PS_OK; } } //add new client { psClient_t *newClient = new psClient_t(); newClient->messageHandler = msgHandler; newClient->topicList.insert(topicId); //add new subscription clientList.insert(newClient); if (topicId >= topic_count) { PS_DEBUG("pub: new client subscribed to topic %i", topicId); } else { PS_DEBUG("pub: new client subscribed to topic %s", topic_names[topicId]); } } UNLOCK_MUTEX(pubsubMtx); return PS_OK; }
int loadMusic( sp_session *session, char *uri , char *name , playqueue_fifo_t *playqueue ) { TRACE_2( PLAYERMANAGER , "loadMusic()."); int status = PC_SUCCESS; char response[255] = { 0 }; /* If it's the first time we load a track, we have to init the audio driver and the playqueue */ // if( firstTime++ == 0 ) // initPlayerEnv(); LOCK_MUTEX( PLAYERMANAGER , &mutexSession ); sp_track *track = NULL; currentTrack = track; if( createTrackFromUri( uri , name ) == PC_ERROR ) status = PC_ERROR; if( currentTrack != NULL) { TRACE_1( PLAYERMANAGER , "Adding track to the playlist."); addTracksToPlayqueue( playqueue , currentTrack ); snprintf( response , 255 , "OK"); sendVoid( ( void * )response , strlen( response ) ); } else { TRACE_ERROR( PLAYERMANAGER , "Cannot add track to the playlist because track is NULL."); status = PC_ERROR; snprintf( response , 255 , "NOK: Cannot add the track to the playlist because the URI might be invalid."); sendVoid( ( void * )response , strlen( response ) ); } UNLOCK_MUTEX( PLAYERMANAGER , &mutexSession ); return status; }
/*! \fn qint64 Win_QextSerialPort::bytesAvailable() Returns the number of bytes waiting in the port's receive queue. This function will return 0 if the port is not currently open, or -1 on error. Error information can be retrieved by calling Win_QextSerialPort::getLastError(). */ qint64 Win_QextSerialPort::bytesAvailable() { LOCK_MUTEX(); if (isOpen()) { DWORD Errors; COMSTAT Status; bool success=ClearCommError(Win_Handle, &Errors, &Status); translateError(Errors); if (success) { lastErr=E_NO_ERROR; UNLOCK_MUTEX(); return Status.cbInQue + QIODevice::bytesAvailable(); } UNLOCK_MUTEX(); return (unsigned int)-1; } UNLOCK_MUTEX(); return 0; }
int workqueue_job_running(struct workqueue_ctx* ctx, int job_id) { int ret = 0; if (!ctx) return -1; do { LOCK_MUTEX(&ctx->mutex); ret = _is_job_running(ctx, job_id); UNLOCK_MUTEX(&ctx->mutex); } while (ret == -EBUSY); return ret; }
bool CCAN232Obj::setMask(unsigned long mask) { char buf[ 20 ]; char szCmd[ 80 ]; LOCK_MUTEX(m_can232ObjMutex); // Acceptance Mask sprintf(buf, "m%8.8lX\r", mask); m_can232obj.m_comm.comm_puts(buf, strlen(buf), true); *szCmd = 0; m_can232obj.m_comm.comm_gets(szCmd, sizeof( szCmd), 100000); printf("Open: Response: setFilter: [%s]\n", szCmd); UNLOCK_MUTEX(m_can232ObjMutex); return true; }
bool CVectorObj::close( void ) { // Do nothing if already terminated if ( !m_bRun ) return false; m_bRun = false; ncdClosePort( m_portHandle ); m_portHandle = INVALID_PORTHANDLE; ncdCloseDriver(); UNLOCK_MUTEX( m_vectorMutex ); LOCK_MUTEX( m_vectorMutex ); // terminate the worker thread #ifdef WIN32 DWORD rv; // Wait for transmit thread to terminate while ( true ) { GetExitCodeThread( m_hTreadTransmit, &rv ); if ( STILL_ACTIVE != rv ) break; } // Wait for receive thread to terminate while ( true ) { GetExitCodeThread( m_hTreadReceive, &rv ); if ( STILL_ACTIVE != rv ) break; } #else int *trv; pthread_join( m_threadIdReceive, (void **)&trv ); pthread_join( m_threadIdTransmit, (void **)&trv ); pthread_mutex_destroy( &m_vectorMutex ); #endif return true; }
void end_of_track( sp_session *session ) { TRACE_2( PLAYERMANAGER , "end_of_track()."); TRACE_3( PLAYERMANAGER , "End of track..."); // LOCK_MUTEX( PLAYERMANAGER , &mutexSession ); TRACE_3( PLAYERMANAGER , "Removing the track which have been played."); sp_track_release( currentTrack ); // UNLOCK_MUTEX( PLAYERMANAGER , &mutexSession ); // if( hasNextTrack() == TRUE ) // { // TRACE_1( PLAYERMANAGER , "Load next music !"); // playMusic( session , "" , currentStreamName ); // } if( nextTrackInStream( currentStreamName ) == PC_SUCCESS ) { TRACE_1( PLAYERMANAGER , "Load next music !"); } else { TRACE_WARNING( PLAYERMANAGER , "No more music in the mainplaylist"); audio_fifo_flush( &g_audiofifo ); LOCK_MUTEX( PLAYERMANAGER , &mutexSession ); sp_session_player_play( session , 0 ); sp_session_player_unload( session ); UNLOCK_MUTEX( PLAYERMANAGER , &mutexSession ); playing = FALSE; } }
/*! \fn void Posix_QextSerialPort::setTimeout(ulong sec); Sets the read and write timeouts for the port to millisec milliseconds. Note that this is a per-character timeout, i.e. the port will wait this long for each individual character, not for the whole read operation. This timeout also applies to the bytesWaiting() function. \note POSIX does not support millisecond-level control for I/O timeout values. Any timeout set using this function will be set to the next lowest tenth of a second for the purposes of detecting read or write timeouts. For example a timeout of 550 milliseconds will be seen by the class as a timeout of 500 milliseconds for the purposes of reading and writing the port. However millisecond-level control is allowed by the select() system call, so for example a 550-millisecond timeout will be seen as 550 milliseconds on POSIX systems for the purpose of detecting available bytes in the read buffer. */ void Posix_QextSerialPort::setTimeout(long millisec) { LOCK_MUTEX(); Settings.Timeout_Millisec = millisec; Posix_Copy_Timeout.tv_sec = millisec / 1000; Posix_Copy_Timeout.tv_usec = millisec % 1000; if (isOpen()) { if (millisec == -1) fcntl(fd, F_SETFL, O_NDELAY); else //O_SYNC should enable blocking ::write() //however this seems not working on Linux 2.6.21 (works on OpenBSD 4.2) fcntl(fd, F_SETFL, O_SYNC); tcgetattr(fd, & Posix_CommConfig); Posix_CommConfig.c_cc[VTIME] = millisec/100; tcsetattr(fd, TCSAFLUSH, & Posix_CommConfig); } UNLOCK_MUTEX(); }
//suscribe to topic Id. Transport version. ps_result_enum ps_pubsub_class::subscribe(ps_topic_id_t topicId, ps_transport_class *pst) { if (topicId >= topic_count) { PS_DEBUG("pub: subscribe to %i from %s", topicId, pst->name.c_str()); } else { PS_DEBUG("pub: subscribe to %s from %s", topic_names[ topicId], pst->name.c_str()); } LOCK_MUTEX(pubsubMtx); //insert the topic pst->topicList.insert(topicId); //add new subscription UNLOCK_MUTEX(pubsubMtx); return PS_OK; }
BOOL CDllDrvObj::removeAllObjects() { LOCK_MUTEX( m_objMutex ); for ( int i=0; i<CANAL_USB2CAN_DRIVER_MAX_OPEN; i++ ) { if ( NULL != m_drvObjArray[ i ] ) { m_drvObjArray[ i ]->close(); delete m_drvObjArray[ i ]; m_drvObjArray[ i ] = NULL; lpvMem[i] = 0;//inform global space driver on position i closed } } UNLOCK_MUTEX( m_objMutex ); return TRUE; }
void buffer_append_action_at (buf_t *buf, action_func_t action_func, void *action_arg, ogg_int64_t position) { action_t *action; action = malloc_action(action_func, action_arg); pthread_cleanup_push(buffer_mutex_unlock, buf); LOCK_MUTEX(buf->mutex); action->position = position; in_order_add_action(&buf->actions, action, APPEND); UNLOCK_MUTEX(buf->mutex); pthread_cleanup_pop(0); }
bool CApoxObj::close( void ) { // Do nothing if already terminated if ( !m_bRun ) return false; m_bRun = false; // Switch to boot mode setAdapterRunMode( RUNMODE_BOOT ); FT_Close( m_ftHandle ); UNLOCK_MUTEX( m_apoxMutex ); LOCK_MUTEX( m_apoxMutex ); // terminate the worker thread #ifdef WIN32 DWORD rv; // Wait for transmit thread to terminate while ( true ) { GetExitCodeThread( m_hTreadTransmit, &rv ); if ( STILL_ACTIVE != rv ) break; } // Wait for receive thread to terminate while ( true ) { GetExitCodeThread( m_hTreadReceive, &rv ); if ( STILL_ACTIVE != rv ) break; } #else int *trv; pthread_join( m_threadIdReceive, (void **)&trv ); pthread_join( m_threadIdTransmit, (void **)&trv ); pthread_mutex_destroy( &m_apoxMutex ); #endif return true; }
/*! \fn void Win_QextSerialPort::close() Closes a serial port. This function has no effect if the serial port associated with the class is not currently open. */ void Win_QextSerialPort::close() { LOCK_MUTEX(); if (isOpen()) { flush(); if (overlapThread->isRunning()) { overlapThread->stop(); if (QThread::currentThread() != overlapThread) overlapThread->wait(); } if (CloseHandle(Win_Handle)) Win_Handle = INVALID_HANDLE_VALUE; _bytesToWrite = 0; QIODevice::close(); } UNLOCK_MUTEX(); }
/*! \fn qint64 Win_QextSerialPort::readData(char *data, qint64 maxSize) Reads a block of data from the serial port. This function will read at most maxlen bytes from the serial port and place them in the buffer pointed to by data. Return value is the number of bytes actually read, or -1 on error. \warning before calling this function ensure that serial port associated with this class is currently open (use isOpen() function to check if port is open). */ qint64 Win_QextSerialPort::readData(char *data, qint64 maxSize) { DWORD retVal; LOCK_MUTEX(); retVal = 0; if (queryMode() == QextSerialBase::EventDriven) { OVERLAPPED overlapRead; overlapRead.Internal = 0; overlapRead.InternalHigh = 0; overlapRead.Offset = 0; overlapRead.OffsetHigh = 0; overlapRead.hEvent = CreateEvent(NULL, true, false, NULL); if (!ReadFile(m_WinHandle, (void*)data, (DWORD)maxSize, & retVal, & overlapRead)) { if (GetLastError() == ERROR_IO_PENDING) { GetOverlappedResult(m_WinHandle, & overlapRead, & retVal, true); } else { lastErr = E_READ_FAILED; retVal = (DWORD)-1; } } CloseHandle(overlapRead.hEvent); } else if (!ReadFile(m_WinHandle, (void*)data, (DWORD)maxSize, & retVal, NULL)) { lastErr = E_READ_FAILED; retVal = (DWORD)-1; } UNLOCK_MUTEX(); return (qint64)retVal; }
/*! \fn void Win_QextSerialPort::setTimeout(ulong millisec); Sets the read and write timeouts for the port to millisec milliseconds. Setting 0 for both sec and millisec indicates that timeouts are not used for read nor write operations. Setting -1 indicates that read and write should return immediately. \note this function does nothing in event driven mode. */ void Win_QextSerialPort::setTimeout(long millisec) { LOCK_MUTEX(); Settings.Timeout_Millisec = millisec; if (millisec == -1) { Win_CommTimeouts.ReadIntervalTimeout = MAXDWORD; Win_CommTimeouts.ReadTotalTimeoutConstant = 0; } else { Win_CommTimeouts.ReadIntervalTimeout = millisec; Win_CommTimeouts.ReadTotalTimeoutConstant = millisec; } Win_CommTimeouts.ReadTotalTimeoutMultiplier = 0; Win_CommTimeouts.WriteTotalTimeoutMultiplier = millisec; Win_CommTimeouts.WriteTotalTimeoutConstant = 0; if (queryMode() != QextSerialBase::EventDriven) SetCommTimeouts(Win_Handle, &Win_CommTimeouts); UNLOCK_MUTEX(); }
long CSocketcanApp::addDriverObject(CSocketcanObj *plog) { long h = 0; LOCK_MUTEX(m_objMutex); for (int i = 0; i < CANAL_SOCKETCAN_DRIVER_MAX_OPEN; i++) { if (NULL == m_socketcanArray[ i ]) { m_socketcanArray[ i ] = plog; h = i + 1681; break; } } UNLOCK_MUTEX(m_objMutex); return h; }
int CCAN232Obj::readMsg(canalMsg *pMsg) { int rv = false; if ((NULL != m_can232obj.m_rcvList.pHead) && (NULL != m_can232obj.m_rcvList.pHead->pObject)) { LOCK_MUTEX(m_can232ObjMutex); memcpy(pMsg, m_can232obj.m_rcvList.pHead->pObject, sizeof( canalMsg)); dll_removeNode(&m_can232obj.m_rcvList, m_can232obj.m_rcvList.pHead); UNLOCK_MUTEX(m_can232ObjMutex); rv = true; } return rv; }
/*! \fn bool Posix_QextSerialPort::open(OpenMode mode) Opens the serial port associated to this class. This function has no effect if the port associated with the class is already open. The port is also configured to the current settings, as stored in the Settings structure. */ bool Posix_QextSerialPort::open(OpenMode mode) { LOCK_MUTEX(); if (mode == QIODevice::NotOpen) return isOpen(); if (!isOpen()) { /*open the port*/ Posix_File->setFileName(port); qDebug("Trying to open File"); if (Posix_File->open(QIODevice::ReadWrite|QIODevice::Unbuffered)) { qDebug("Opened File succesfully"); /*set open mode*/ QIODevice::open(mode); /*configure port settings*/ tcgetattr(Posix_File->handle(), &Posix_CommConfig); /*set up other port settings*/ Posix_CommConfig.c_cflag|=CREAD|CLOCAL; Posix_CommConfig.c_lflag&=(~(ICANON|ECHO|ECHOE|ECHOK|ECHONL|ISIG)); Posix_CommConfig.c_iflag&=(~(INPCK|IGNPAR|PARMRK|ISTRIP|ICRNL|IXANY)); Posix_CommConfig.c_oflag&=(~OPOST); Posix_CommConfig.c_cc[VMIN]=0; Posix_CommConfig.c_cc[VINTR] = _POSIX_VDISABLE; Posix_CommConfig.c_cc[VQUIT] = _POSIX_VDISABLE; Posix_CommConfig.c_cc[VSTART] = _POSIX_VDISABLE; Posix_CommConfig.c_cc[VSTOP] = _POSIX_VDISABLE; Posix_CommConfig.c_cc[VSUSP] = _POSIX_VDISABLE; setBaudRate(Settings.BaudRate); setDataBits(Settings.DataBits); setParity(Settings.Parity); setStopBits(Settings.StopBits); setFlowControl(Settings.FlowControl); // setTimeout(Settings.Timeout_Sec, Settings.Timeout_Millisec); setTimeout(Settings.Timeout_Millisec); tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); } else { qDebug("Could not open File! Error code : %d", Posix_File->error()); } } UNLOCK_MUTEX(); return isOpen(); }
void CDllDrvObj::removeDriverObject( long h ) { long idx = h - 1681; // Check if valid handle if ( idx < 0 || idx >= CANAL_USB2CAN_DRIVER_MAX_OPEN) return; LOCK_MUTEX( m_objMutex ); if ( NULL != m_drvObjArray[ idx ] ) { delete m_drvObjArray[ idx ]; } m_drvObjArray[ idx ] = NULL; lpvMem[idx] = 0;//inform global space driver on position idx closed UNLOCK_MUTEX( m_objMutex ); }
/*! \fn void Win_QextSerialPort::setParity(ParityType parity) Sets the parity associated with the serial port. The possible values of parity are: \verbatim PAR_SPACE Space Parity PAR_MARK Mark Parity PAR_NONE No Parity PAR_EVEN Even Parity PAR_ODD Odd Parity \endverbatim */ void Win_QextSerialPort::setParity(ParityType parity) { LOCK_MUTEX(); if (Settings.Parity!=parity) { Settings.Parity=parity; } if (isOpen()) { Win_CommConfig.dcb.Parity=(unsigned char)parity; switch (parity) { /*space parity*/ case PAR_SPACE: if (Settings.DataBits==DATA_8) { TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: Space parity with 8 data bits is not supported by POSIX systems."); } Win_CommConfig.dcb.fParity=TRUE; break; /*mark parity - WINDOWS ONLY*/ case PAR_MARK: TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: Mark parity is not supported by POSIX systems"); Win_CommConfig.dcb.fParity=TRUE; break; /*no parity*/ case PAR_NONE: Win_CommConfig.dcb.fParity=FALSE; break; /*even parity*/ case PAR_EVEN: Win_CommConfig.dcb.fParity=TRUE; break; /*odd parity*/ case PAR_ODD: Win_CommConfig.dcb.fParity=TRUE; break; } SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); } UNLOCK_MUTEX(); }
//called by broker thread to send a message to all subscribers //these messages go to plumbing void ps_pubsub_class::forward_system_packet(const void *msg, int len) { //access the pubsub prefix ps_pubsub_header_t* prefix = (ps_pubsub_header_t*)(msg); ps_packet_type_t packet_type = (prefix->packet_type); if (packet_type < PACKET_TYPES_COUNT) { // PS_DEBUG("pub: publish_system_packet(%s)", packet_type_names[packet_type]); LOCK_MUTEX(pubsubMtx); if (prefix->packet_source == SOURCE) { //local source - send to all transports for (auto trns : transports) { PS_DEBUG("pub: sending %s to %s", packet_type_names[packet_type], trns->name.c_str()); trns->send_packet(msg, len); } } else { //remote source - send to registered objects void *message = (void*) ((uint8_t*) msg + sizeof(ps_pubsub_header_t)); int length = len - sizeof(ps_pubsub_header_t); std::set<ps_root_class *> rcl_set = registered_objects[packet_type]; for (ps_root_class *rcl : rcl_set) { PS_DEBUG("pub: sending %s to %s", packet_type_names[packet_type], rcl->name.c_str()); rcl->message_handler(prefix->packet_source, packet_type, message, length); } } UNLOCK_MUTEX(pubsubMtx); } else { PS_ERROR("pub: packet_type %i!", packet_type); } }
CVSCPL2App::~CVSCPL2App() { LOCK_MUTEX( m_objMutex ); for ( int i = 0; i<VSCP_LEVEL1_INTERFACE_MAX_OPEN; i++ ) { if ( NULL != m_pvscpifArray[ i ] ) { Clmsensors *plmif = getDriverObject( i ); if ( NULL != plmif ) { plmif->close(); delete m_pvscpifArray[ i ]; m_pvscpifArray[ i ] = NULL; } } } UNLOCK_MUTEX( m_objMutex ); pthread_mutex_destroy( &m_objMutex ); }
void buffer_append_action_at_end (buf_t *buf, action_func_t action_func, void *action_arg) { action_t *action; action = malloc_action(action_func, action_arg); pthread_cleanup_push(buffer_mutex_unlock, buf); LOCK_MUTEX(buf->mutex); /* Stick after the last item in the buffer */ action->position = buf->position_end; in_order_add_action(&buf->actions, action, APPEND); UNLOCK_MUTEX(buf->mutex); pthread_cleanup_pop(0); }
CVSCPDrvApp::~CVSCPDrvApp() { LOCK_MUTEX( m_objMutex ); for ( int i = 0; i < VSCP_RPILCD_DRIVER_MAX_OPEN; i++ ) { if ( NULL == m_pPiLCDArray[ i ] ) { CRpiLCD *prpimax6675 = getDriverObject(i); if ( NULL != prpimax6675 ) { prpimax6675->close(); delete m_pPiLCDArray[ i ]; m_pPiLCDArray[ i ] = NULL; } } } UNLOCK_MUTEX( m_objMutex ); pthread_mutex_destroy( &m_objMutex ); }
CLoggerdllApp::~CLoggerdllApp() { LOCK_MUTEX(m_objMutex); for (int i = 0; i < CANAL_LOGGER_DRIVER_MAX_OPEN; i++) { if (NULL == m_logArray[ i ]) { CLog *pLog = getDriverObject(i); if (NULL != pLog) { pLog->close(); delete m_logArray[ i ]; m_logArray[ i ] = NULL; } } } UNLOCK_MUTEX(m_objMutex); pthread_mutex_destroy(&m_objMutex); }
CSocketcanApp::~CSocketcanApp() { LOCK_MUTEX(m_objMutex); for (int i = 0; i < CANAL_SOCKETCAN_DRIVER_MAX_OPEN; i++) { if (NULL == m_socketcanArray[ i ]) { CSocketcanObj *pCAN232Obj = getDriverObject(i); if (NULL != pCAN232Obj) { pCAN232Obj->close(); delete m_socketcanArray[ i ]; m_socketcanArray[ i ] = NULL; } } } UNLOCK_MUTEX(m_objMutex); pthread_mutex_destroy(&m_objMutex); }
CVSCPDrvApp::~CVSCPDrvApp() { LOCK_MUTEX(m_objMutex); for (int i = 0; i < VSCP_TCPIPLINK_DRIVER_MAX_OPEN; i++) { if (NULL != m_ptcpiplinkArray[ i ]) { CTcpipLink *psockcan = getDriverObject(i); if (NULL != psockcan) { psockcan->close(); delete m_ptcpiplinkArray[ i ]; m_ptcpiplinkArray[ i ] = NULL; } } } UNLOCK_MUTEX(m_objMutex); pthread_mutex_destroy(&m_objMutex); }
CVSCPL1App::~CVSCPL1App() { LOCK_MUTEX( m_objMutex ); for ( int i = 0; i<VSCP_LEVEL1_INTERFACE_MAX_OPEN; i++ ) { if ( NULL == m_pvscpifArray[ i ] ) { VscpTcpIf *pvscpif = getDriverObject( i ); if ( NULL != pvscpif ) { pvscpif->doCmdClose(); delete m_pvscpifArray[ i ]; m_pvscpifArray[ i ] = NULL; } } } UNLOCK_MUTEX( m_objMutex ); pthread_mutex_destroy( &m_objMutex ); }
CVSCPDrvApp::~CVSCPDrvApp() { LOCK_MUTEX(m_objMutex); for (int i = 0; i < VSCP_RAWETHERNET_DRIVER_MAX_OPEN; i++) { if (NULL == m_prawethernetArray[ i ]) { CRawEthernet *psockcan = getDriverObject(i); if (NULL != psockcan) { psockcan->close(); delete m_prawethernetArray[ i ]; m_prawethernetArray[ i ] = NULL; } } } UNLOCK_MUTEX(m_objMutex); pthread_mutex_destroy(&m_objMutex); }