/* The internal event handlers for PhidgetManager - these should be called directly from the usb functions... * these run in the context of the central thread * if AddDevice returns EPHIDGET_DUPLICATE, the user callback is not run (good) */ int CPhidgetAttachEvent(CPhidgetHandle phid) { int result = 0; CPhidgetManagerList *trav2 = 0; TESTPTR(phid) result = CList_addToList((CListHandle *)&AttachedDevices, phid, CPhidget_areEqual); if(result == EPHIDGET_DUPLICATE) { return EPHIDGET_OK; } else if(result) { return result; } for(trav2 = localPhidgetManagers; trav2; trav2 = trav2->next) { if (trav2->phidm->fptrAttachChange && trav2->phidm->state == PHIDGETMANAGER_ACTIVE) { //So we can access AttachedDevices from within the manager atach event CThread_mutex_unlock(&attachedDevicesLock); trav2->phidm->fptrAttachChange((CPhidgetHandle)phid, trav2->phidm->fptrAttachChangeptr); CThread_mutex_lock(&attachedDevicesLock); } } return findActiveDevice(phid); }
int CCONV CPhidgetDictionary_getKey(CPhidgetDictionaryHandle dict, const char *key, char *val, int vallen) { int result, size; char err[1024], *keywrap; TESTPTRS(dict, key) TESTPTR(val) CThread_mutex_lock(&dict->lock); if(!CPhidget_statusFlagIsSet(dict->status, PHIDGET_SERVER_CONNECTED_FLAG)) { CThread_mutex_unlock(&dict->lock); return EPHIDGET_NETWORK_NOTCONNECTED; } //The get command returns a list of keys - since we want just a single key, lets wrap in ^ and $ //other reg exp tags are allowed and will be honoured size = (int)strlen(key); keywrap = (char *)malloc(size+3); snprintf(keywrap, size+3, "^%s$",key); CThread_mutex_lock(&dict->networkInfo->server->pdc_lock); result = pdc_get(dict->networkInfo->server->pdcs, keywrap, val, vallen, err, sizeof(err)); CThread_mutex_unlock(&dict->networkInfo->server->pdc_lock); free(keywrap); CThread_mutex_unlock(&dict->lock); if(result == 0) return EPHIDGET_UNEXPECTED; return EPHIDGET_OK; }
int CCONV CPhidgetDictionary_set_OnServerDisconnect_Handler(CPhidgetDictionaryHandle dict, int (CCONV *fptr)(CPhidgetDictionaryHandle dict, void *userPtr), void *userPtr) { TESTPTR(dict) dict->fptrServerDisconnect = fptr; dict->fptrServerDisconnectptr = userPtr; return EPHIDGET_OK; }
int CCONV CPhidgetManager_set_OnServerDisconnect_Handler(CPhidgetManagerHandle phidm, int (CCONV *fptr)(CPhidgetManagerHandle phidm, void *userPtr), void *userPtr) { TESTPTR(phidm) phidm->fptrDisconnect = fptr; phidm->fptrDisconnectptr = userPtr; return EPHIDGET_OK; }
int CCONV CPhidgetManager_set_OnDetach_Handler(CPhidgetManagerHandle phidm, int (CCONV *fptr)(CPhidgetHandle phid, void *userPtr), void *userPtr) { TESTPTR(phidm) phidm->fptrDetachChange = fptr; phidm->fptrDetachChangeptr = userPtr; return EPHIDGET_OK; }
int cjld_list_getid(cjld_list *list) { TESTPTR(cjld_list_get_id, list); return list->id; }//
/* this takes any list, and frees all of the list element, and can also free the elements that they point to */ int CList_emptyList(CListHandle *list, int freeDevices, void (*free_fptr)(void *element)) { CListHandle last = 0, traverse = 0; TESTPTR(list) last = 0; for(traverse = *list; traverse; last = traverse, traverse = traverse->next) { if(traverse->element && freeDevices) { free_fptr(traverse->element); traverse->element = 0; } if(last) { free(last); last = NULL; } } if(last) { free(last); last = NULL; } *list = 0; return EPHIDGET_OK; }
int CCONV CPhidgetManager_set_OnError_Handler(CPhidgetManagerHandle phidm, int(CCONV *fptr)(CPhidgetManagerHandle, void *, int, const char *), void *userPtr) { TESTPTR(phidm) phidm->fptrError = fptr; phidm->fptrErrorptr = userPtr; return EPHIDGET_OK; }
int CCONV CPhidgetDictionary_set_OnError_Handler(CPhidgetDictionaryHandle dict, int(CCONV *fptr)(CPhidgetDictionaryHandle, void *, int, const char *), void *userPtr) { TESTPTR(dict) dict->fptrError = fptr; dict->fptrErrorptr = userPtr; return EPHIDGET_OK; }
/** * * s[i:j] * s[ * * Case 1: empty list * Case 2: one element * Case 3: * */ int *cjld_list_slice(cjld_list *list, int start, int stop) { TESTPTR(cjld_list_insert, list); TESTINDEX(cjld_list_insert, start); TESTINDEX(cjld_list_insert, stop); }//
int CCONV CPhidgetDictionary_set_OnKeyChange_Handler(CPhidgetDictionaryHandle dict, CPhidgetDictionaryListenerHandle *dictlistener, const char *pattern, int(CCONV *fptr)(CPhidgetDictionaryHandle dict, void *userPtr, const char *key, const char *val, CPhidgetDictionary_keyChangeReason reason), void *userPtr) { CPhidgetDictionaryListenerHandle dict_listener; char errdesc[1024]; int result; TESTPTRS(dict, pattern) TESTPTR(dictlistener) CThread_mutex_lock(&dict->lock); if(!CPhidget_statusFlagIsSet(dict->status, PHIDGET_SERVER_CONNECTED_FLAG)) { CThread_mutex_unlock(&dict->lock); return EPHIDGET_NETWORK_NOTCONNECTED; } if(!(dict_listener = malloc(sizeof(CPhidgetDictionaryListener)))) { CThread_mutex_unlock(&dict->lock); return EPHIDGET_NOMEMORY; } ZEROMEM(dict_listener, sizeof(CPhidgetDictionaryListener)); dict_listener->dict = dict; dict_listener->fptr = fptr; dict_listener->userPtr = userPtr; CThread_mutex_lock(&dict->networkInfo->server->pdc_lock); if (!(dict_listener->listen_id = pdc_listen(dict->networkInfo->server->pdcs, pattern, dict_event_handler, dict_listener, errdesc, sizeof (errdesc)))) { LOG(PHIDGET_LOG_DEBUG,"pdc_listen: %s", errdesc); free(dict_listener); CThread_mutex_unlock(&dict->networkInfo->server->pdc_lock); CThread_mutex_unlock(&dict->lock); return EPHIDGET_UNEXPECTED; } CThread_mutex_unlock(&dict->networkInfo->server->pdc_lock); CThread_mutex_lock(&dict->listenersLock); if((result = CList_addToList((CListHandle *)&dict->listeners, dict_listener, CPhidgetDictionaryListener_areEqual))) { CThread_mutex_unlock(&dict->listenersLock); CThread_mutex_lock(&dict->networkInfo->server->pdc_lock); pdc_ignore(dict->networkInfo->server->pdcs, dict_listener->listen_id, NULL, 0); CThread_mutex_unlock(&dict->networkInfo->server->pdc_lock); free(dict_listener); CThread_mutex_unlock(&dict->lock); return result; } CThread_mutex_unlock(&dict->listenersLock); CThread_mutex_unlock(&dict->lock); *dictlistener = dict_listener; return EPHIDGET_OK; }
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; }
int cjld_list_destroy(cjld_list *list) { TESTPTR(cjld_list_destroy, list); void (*cleaner)(void *, int); cleaner = list->cleaner; if (NULL==cleaner) cleaner = &__cjld_cleaner_free; cjld_list_visit( list, cleaner ); free(list); }//
int CCONV CPhidgetManager_close(CPhidgetManagerHandle phidm) { TESTPTR(phidm) CThread_mutex_lock(&phidm->openCloseLock); if (!CPhidget_statusFlagIsSet(phidm->status, PHIDGET_OPENED_FLAG)) { LOG(PHIDGET_LOG_WARNING, "Close was called on an already closed Manager handle."); CThread_mutex_unlock(&phidm->openCloseLock); return EPHIDGET_OK; } if(phidm->state == PHIDGETMANAGER_ACTIVE || phidm->state == PHIDGETMANAGER_ACTIVATING) { phidm->state = PHIDGETMANAGER_INACTIVE; CPhidget_clearStatusFlag(&phidm->status, PHIDGET_ATTACHED_FLAG, &phidm->lock); if(CPhidget_statusFlagIsSet(phidm->status, PHIDGET_REMOTE_FLAG)) { //Only free the list phidgets if this is an openRemoteIP - not for openRemote int freeList = phidm->networkInfo->mdns ? PFALSE : PTRUE; unregisterRemoteManager(phidm); CList_emptyList((CListHandle *)&phidm->AttachedPhidgets, freeList, CPhidget_free); } else { CThread_mutex_lock(&managerLock); ActivePhidgetManagers--; CList_removeFromList((CListHandle *)&localPhidgetManagers, phidm, CPhidgetManager_areEqual, PFALSE, NULL); CThread_mutex_unlock(&managerLock); } } //if there are no more active phidgets or managers, wait for the central thread to exit if(!ActiveDevices && !ActivePhidgetManagers) { JoinCentralThread(); //Shut down USB #if defined(_LINUX) && !defined(_ANDROID) CUSBUninit(); #endif } CPhidget_clearStatusFlag(&phidm->status, PHIDGET_OPENED_FLAG, &phidm->lock); CThread_mutex_unlock(&phidm->openCloseLock); return EPHIDGET_OK; }
int CCONV CPhidgetManager_open(CPhidgetManagerHandle phidm) { int result = EPHIDGET_OK; TESTPTR(phidm) CThread_mutex_lock(&phidm->openCloseLock); if (CPhidget_statusFlagIsSet(phidm->status, PHIDGET_OPENED_FLAG)) { LOG(PHIDGET_LOG_WARNING, "Open was called on an already opened Manager handle."); CThread_mutex_unlock(&phidm->openCloseLock); return EPHIDGET_OK; } if(!phidgetLocksInitialized) { CThread_mutex_init(&activeDevicesLock); CThread_mutex_init(&attachedDevicesLock); phidgetLocksInitialized = PTRUE; } if(phidm->state == PHIDGETMANAGER_INACTIVE) { CThread_mutex_lock(&managerLock); CList_addToList((CListHandle *)&localPhidgetManagers, phidm, CPhidgetManager_areEqual); #ifdef _MACOSX phidm->state = PHIDGETMANAGER_ACTIVE; #else phidm->state = PHIDGETMANAGER_ACTIVATING; #endif CPhidget_setStatusFlag(&phidm->status, PHIDGET_ATTACHED_FLAG, &phidm->lock); ActivePhidgetManagers++; CThread_mutex_unlock(&managerLock); result = StartCentralThread(); } CPhidget_setStatusFlag(&phidm->status, PHIDGET_OPENED_FLAG, &phidm->lock); CThread_mutex_unlock(&phidm->openCloseLock); return result; }
/* Async add - errors returned to a registered error handler */ int CCONV CPhidgetDictionary_addKey(CPhidgetDictionaryHandle dict, const char *key, const char *val, int persistent) { TESTPTR(dict) TESTPTRS(key, val) CThread_mutex_lock(&dict->lock); if(!CPhidget_statusFlagIsSet(dict->status, PHIDGET_SERVER_CONNECTED_FLAG)) { CThread_mutex_unlock(&dict->lock); return EPHIDGET_NETWORK_NOTCONNECTED; } pdc_async_set(dict->networkInfo->server->pdcs, key, val, (int)strlen(val), persistent?0:1, internal_async_network_error_handler, dict); CThread_mutex_unlock(&dict->lock); return EPHIDGET_OK; }
/** * Case 1: HEAD insertion * Case 2: TAIL insertion * Case 3: In between */ int cjld_list_insert(cjld_list *list, void *el, int id, int pos) { TESTPTR(cjld_list_insert, list); TESTINDEX(cjld_list_insert, pos); TESTINDEXU(cjld_list_insert, pos, list->count ); int i=0; cjld_snode *current = NULL, *previous = NULL, *node = NULL; //create node node = (cjld_snode *) malloc( sizeof(cjld_snode *) ); node->el = el; node->id = id; //case 1 if (0==pos) { node->next = list->head; list->head = node; list->count++; return 1; } //case 2 & 3: need to walk the list // as it is single-linked // NOTE: tail pointer never needs to be updated current = list->head; previous = NULL; //walk till pos while( i != pos ) { previous=current; current=current->next; i++; }//while //insert in-between previous->next = node; node->next = current; return 1; }//
int CCONV CPhidgetManager_close(CPhidgetManagerHandle phidm) { TESTPTR(phidm) CThread_mutex_lock(&phidm->openCloseLock); if (!CPhidget_statusFlagIsSet(phidm->status, PHIDGET_OPENED_FLAG)) { LOG(PHIDGET_LOG_WARNING, "Close was called on an already closed Manager handle."); CThread_mutex_unlock(&phidm->openCloseLock); return EPHIDGET_OK; } if(phidm->state == PHIDGETMANAGER_ACTIVE || phidm->state == PHIDGETMANAGER_ACTIVATING) { phidm->state = PHIDGETMANAGER_INACTIVE; CPhidget_clearStatusFlag(&phidm->status, PHIDGET_ATTACHED_FLAG, &phidm->lock); if(CPhidget_statusFlagIsSet(phidm->status, PHIDGET_REMOTE_FLAG)) { unregisterRemoteManager(phidm); } else { CThread_mutex_lock(&managerLock); ActivePhidgetManagers--; CList_removeFromList((CListHandle *)&localPhidgetManagers, phidm, CPhidgetManager_areEqual, PFALSE, NULL); CThread_mutex_unlock(&managerLock); } } //if there are no more active phidgets or managers, wait for the central thread to exit if(!ActiveDevices && !ActivePhidgetManagers) { JoinCentralThread(); } CPhidget_clearStatusFlag(&phidm->status, PHIDGET_OPENED_FLAG, &phidm->lock); CThread_mutex_unlock(&phidm->openCloseLock); return EPHIDGET_OK; }
int CCONV CPhidgetDictionary_close(CPhidgetDictionaryHandle dict) { int result = EPHIDGET_OK; TESTPTR(dict) CThread_mutex_lock(&dict->openCloseLock); if (!CPhidget_statusFlagIsSet(dict->status, PHIDGET_OPENED_FLAG)) { LOG(PHIDGET_LOG_WARNING, "Close was called on an already closed Dictionary handle."); CThread_mutex_unlock(&dict->openCloseLock); return EPHIDGET_OK; } if((result = unregisterRemoteDictionary(dict)) != EPHIDGET_OK) { CThread_mutex_unlock(&dict->openCloseLock); return result; } CPhidget_clearStatusFlag(&dict->status, PHIDGET_OPENED_FLAG, &dict->lock); CThread_mutex_unlock(&dict->openCloseLock); return EPHIDGET_OK; }
//This can be called even when not connected to a server int CCONV CPhidgetDictionary_remove_OnKeyChange_Handler(CPhidgetDictionaryListenerHandle keylistener) { int result = 0; char errdesc[1024]; CPhidgetDictionaryHandle dict; TESTPTR(keylistener) dict = keylistener->dict; CThread_mutex_lock(&dict->lock); if(CPhidget_statusFlagIsSet(dict->status, PHIDGET_SERVER_CONNECTED_FLAG)) { CThread_mutex_lock(&dict->networkInfo->server->pdc_lock); if(!(result = pdc_ignore(dict->networkInfo->server->pdcs, keylistener->listen_id, errdesc, sizeof (errdesc)))) { LOG(PHIDGET_LOG_WARNING,"pdc_ignore: %s",errdesc); CThread_mutex_unlock(&dict->networkInfo->server->pdc_lock); CThread_mutex_unlock(&dict->lock); return EPHIDGET_UNEXPECTED; } CThread_mutex_unlock(&dict->networkInfo->server->pdc_lock); } CThread_mutex_lock(&dict->listenersLock); if((result = CList_removeFromList((CListHandle *)&dict->listeners, keylistener, CPhidgetDictionaryListener_areEqual, PTRUE, CPhidgetDictionaryListener_free))) { CThread_mutex_unlock(&dict->listenersLock); CThread_mutex_unlock(&dict->lock); return result; } CThread_mutex_unlock(&dict->listenersLock); CThread_mutex_unlock(&dict->lock); return EPHIDGET_OK; }
int cjld_list_append( cjld_list *dest, void *el, int id ) { TESTPTR(cjld_list_append, dest); int code = 1; //optimistic cjld_snode *new_node; new_node = (cjld_snode *) malloc(sizeof(cjld_snode)); if (NULL!=new_node) { // new node... new_node->el = el; new_node->next = NULL; // there is a tail... put at the end if (NULL!=dest->tail) (dest->tail)->next=new_node; // point tail to the new element dest->tail = new_node; // adjust head if (NULL==dest->head) dest->head=new_node; dest->count++; } else { code = 0; } return code; }//
void *cjld_list_remove(cjld_list *list, int id) { TESTPTR(cjld_list_remove, list); void *element=NULL; cjld_snode *current_node=list->head, *previous_node=NULL, *removed_node=NULL; while(NULL!=current_node) { if (id == current_node->id) { removed_node = current_node; break; } previous_node = current_node; current_node = current_node->next; }; //case 1: only one element and it is the one to remove => adjust both head & tail //case 2: one element to remove from a plurality of elements // a) element at the tail => use previous element to adjust tail // b) element at the head // c) element in between head & tail if (NULL==removed_node) { return NULL; } //case 1 if ( (list->tail==removed_node) && (list->head==removed_node) ) { list->head = NULL; list->tail = NULL; list->count = 0; element = removed_node->el; free(removed_node); return element; } //case 2a if (list->tail == removed_node) { previous_node->next = NULL; list->tail = previous_node; list->count--; element = removed_node->el; free(removed_node); return element; } //case 2b if (list->head == removed_node) { list->head = (list->head)->next; list->count--; element = removed_node->el; free(removed_node); return element; } //case 2c // must join the two list segments previous_node->next = removed_node->next; list->count--; element = removed_node->el; free(removed_node); return element; }//
/* The internal event handlers for PhidgetManager - these should be called directly from the usb functions... * these run in the context of the central thread * if AddDevice returns EPHIDGET_DUPLICATE, the user callback is not run (good) */ int CPhidgetAttachEvent(CPhidgetHandle phid) { int result = 0; CPhidgetList *trav = 0; CPhidgetManagerList *trav2 = 0; CPhidgetHandle travPhid = 0; TESTPTR(phid) result = CList_addToList((CListHandle *)&AttachedDevices, phid, CPhidget_areEqual); if(result == EPHIDGET_DUPLICATE) { return EPHIDGET_OK; } else if(result) { return result; } for(trav2 = localPhidgetManagers; trav2; trav2 = trav2->next) { if (trav2->phidm->fptrAttachChange && trav2->phidm->state == PHIDGETMANAGER_ACTIVE) trav2->phidm->fptrAttachChange((CPhidgetHandle)phid, trav2->phidm->fptrAttachChangeptr); } result = EPHIDGET_OK; CThread_mutex_lock(&activeDevicesLock); //first look for this specific device for (trav=ActiveDevices; trav; trav = trav->next) { if((trav->phid->serialNumber == phid->serialNumber) && (trav->phid->deviceID == phid->deviceID) && !CPhidget_statusFlagIsSet(trav->phid->status, PHIDGET_ATTACHED_FLAG)) { travPhid = trav->phid; CThread_mutex_unlock(&activeDevicesLock); //Prevent close from being called during attachActiveDevice CThread_mutex_lock(&travPhid->openCloseLock); result = attachActiveDevice(travPhid, phid); CThread_mutex_unlock(&travPhid->openCloseLock); return result; } } //second look for a general device for (trav=ActiveDevices; trav; trav = trav->next) { if(CPhidget_areEqual(trav->phid, phid) && !CPhidget_statusFlagIsSet(trav->phid->status, PHIDGET_ATTACHED_FLAG)) { travPhid = trav->phid; CThread_mutex_unlock(&activeDevicesLock); //Prevent close from being called during attachActiveDevice CThread_mutex_lock(&travPhid->openCloseLock); result = attachActiveDevice(travPhid, phid); CThread_mutex_unlock(&travPhid->openCloseLock); //If one doesn't work, try the next one - this would happen if the first one in opened elsewhere if(result != EPHIDGET_OK) { CThread_mutex_lock(&activeDevicesLock); continue; } return result; } } CThread_mutex_unlock(&activeDevicesLock); return result; }
int CCONV CPhidgetManager_getAttachedDevices(CPhidgetManagerHandle phidm, CPhidgetHandle *phidArray[], int *count) { CPhidgetList *trav = 0; int i = 0; TESTPTRS(phidArray, count) TESTPTR(phidm) *count = 0; if(CPhidget_statusFlagIsSet(phidm->status, PHIDGET_REMOTE_FLAG)) { for (trav=phidm->AttachedPhidgets; trav; trav = trav->next) { if (CPhidget_statusFlagIsSet(trav->phid->status, PHIDGET_ATTACHED_FLAG)) (*count)++; } if(*count==0) { *phidArray = NULL; } else { *phidArray = (CPhidgetHandle *)malloc(sizeof(**phidArray) * *count); if (!*phidArray) return EPHIDGET_NOMEMORY; ZEROMEM(*phidArray, sizeof(**phidArray) * *count); for (trav=phidm->AttachedPhidgets, i=0; trav; trav = trav->next) { if (CPhidget_statusFlagIsSet(trav->phid->status, PHIDGET_ATTACHED_FLAG)) { (*phidArray)[i] = trav->phid; i++; } } } } else { CThread_mutex_lock(&attachedDevicesLock); for (trav=AttachedDevices; trav; trav = trav->next) { if (CPhidget_statusFlagIsSet(trav->phid->status, PHIDGET_ATTACHED_FLAG)) (*count)++; } if(*count==0) { *phidArray = NULL; } else { *phidArray = (CPhidgetHandle *)malloc(sizeof(**phidArray) * *count); if (!*phidArray) { CThread_mutex_unlock(&attachedDevicesLock); return EPHIDGET_NOMEMORY; } ZEROMEM(*phidArray, sizeof(**phidArray) * *count); for (trav=AttachedDevices, i=0; trav; trav = trav->next) { if (CPhidget_statusFlagIsSet(trav->phid->status, PHIDGET_ATTACHED_FLAG)) { (*phidArray)[i] = trav->phid; i++; } } } CThread_mutex_unlock(&attachedDevicesLock); } return EPHIDGET_OK; }
int cjld_list_count(cjld_list *list) { TESTPTR(cjld_list_get_id, list); return list->count; }//