void CCONV CPhidget_free(void *arg) { CPhidgetHandle phid = (CPhidgetHandle)arg; if (!phid) return; //Call device specific free function if it exists if(phid->fptrFree) phid->fptrFree(phid); //this is only malloc-ed on windows and linux, not wince or mac #if (defined(_WINDOWS) && !defined(WINCE)) || defined(_LINUX) if (phid->CPhidgetFHandle) { CPhidgetFHandle_free(phid->CPhidgetFHandle); phid->CPhidgetFHandle = NULL; } #endif CThread_mutex_destroy(&phid->lock); CThread_mutex_destroy(&phid->openCloseLock); CThread_mutex_destroy(&phid->writelock); CThread_mutex_destroy(&phid->outputLock); CThread_destroy_event(&phid->writeAvailableEvent); CThread_destroy_event(&phid->writtenEvent); free(phid); phid = NULL; return; }
int CPhidgetDetachEvent(CPhidgetHandle phid) { int result = 0; CPhidgetList *trav = 0; CPhidgetManagerList *trav2 = 0; CPhidgetHandle travPhid = 0; TESTPTR(phid) CPhidget_clearStatusFlag(&phid->status, PHIDGET_ATTACHED_FLAG, NULL); CPhidget_setStatusFlag(&phid->status, PHIDGET_DETACHING_FLAG, NULL); for(trav2 = localPhidgetManagers; trav2; trav2 = trav2->next) { if (trav2->phidm->fptrDetachChange && trav2->phidm->state == PHIDGETMANAGER_ACTIVE) trav2->phidm->fptrDetachChange((CPhidgetHandle)phid, trav2->phidm->fptrDetachChangeptr); } CPhidget_clearStatusFlag(&phid->status, PHIDGET_DETACHING_FLAG, NULL); CThread_mutex_lock(&activeDevicesLock); for (trav=ActiveDevices; trav; trav = trav->next) { if((CPhidget_areExtraEqual(phid, trav->phid) && CPhidget_statusFlagIsSet(trav->phid->status, PHIDGET_ATTACHED_FLAG)) || CPhidgetHandle_areEqual(phid, trav->phid)) { CPhidget_setStatusFlag(&trav->phid->status, PHIDGET_DETACHING_FLAG, &trav->phid->lock); if(trav->phid->specificDevice == 2) trav->phid->specificDevice = 0; trav->phid->writeStopFlag = PTRUE; CThread_set_event(&trav->phid->writeAvailableEvent); //if it's waiting on this event - signal NOW result = CUSBCloseHandle(trav->phid); CThread_join(&trav->phid->writeThread); CThread_join(&trav->phid->readThread); //because trav can be freed during the detach call, don't use it in or after the call travPhid = trav->phid; CThread_mutex_unlock(&activeDevicesLock); if (travPhid->fptrDetach) travPhid->fptrDetach((CPhidgetHandle)travPhid, travPhid->fptrDetachptr); travPhid->deviceIDSpec = 0; CPhidgetFHandle_free(travPhid->CPhidgetFHandle); travPhid->CPhidgetFHandle = NULL; CPhidget_clearStatusFlag(&travPhid->status, PHIDGET_DETACHING_FLAG, &travPhid->lock); CPhidget_clearStatusFlag(&travPhid->status, PHIDGET_USB_ERROR_FLAG, &travPhid->lock); goto found_to_detach; } } CThread_mutex_unlock(&activeDevicesLock); found_to_detach: result = CList_removeFromList((CListHandle *)&AttachedDevices, phid, CPhidget_areExtraEqual, TRUE, CPhidget_free); return result; }