/************************************************************************** * Function : UpnpPrintf * * Parameters: * IN Dbg_Level DLevel: The level of the debug logging. It will decide * whether debug statement will go to standard output, or any of the * log files. * IN Dbg_Module Module: debug will go in the name of this module * IN char *DbgFileName: Name of the file from where debug statement is * coming * IN int DbgLineNo : Line number of the file from where debug statement is * coming * IN char * FmtStr, ...: Variable number of arguments that will go in the * debug statement * * Description: * This functions prints the debug statement either on the startdard output * or log file along with the information from where this debug statement * is coming * Returns: void ***************************************************************************/ DBGONLY( void UpnpPrintf( IN Dbg_Level DLevel, IN Dbg_Module Module, IN char *DbgFileName, IN int DbgLineNo, IN char *FmtStr, ... ) { va_list ArgList; va_start( ArgList, FmtStr ); if( DEBUG_LEVEL < DLevel ) return; if( DEBUG_ALL == 0 ) { switch ( Module ) { case SSDP: if( DEBUG_SSDP == 1 ) break; else return; case SOAP: if( DEBUG_SOAP == 1 ) break; else return; case GENA: if( DEBUG_GENA == 1 ) break; else return; case TPOOL: if( DEBUG_TPOOL == 1 ) break; else return; case MSERV: if( DEBUG_MSERV == 1 ) break; else return; case DOM: if( DEBUG_DOM == 1 ) break; else return; case HTTP: if( DEBUG_HTTP == 1 ) break; else return; case API: if( DEBUG_API == 1 ) break; else return; default: return;} } ithread_mutex_lock( &GlobalDebugMutex ); if( DEBUG_TARGET == 0 ) { if( DbgFileName ) { UpnpDisplayFileAndLine( stdout, DbgFileName, DbgLineNo );} vfprintf( stdout, FmtStr, ArgList ); fflush( stdout );} else { if( DLevel == 0 ) { if( DbgFileName ) { UpnpDisplayFileAndLine( ErrFileHnd, DbgFileName, DbgLineNo );} vfprintf( ErrFileHnd, FmtStr, ArgList ); fflush( ErrFileHnd );} else { if( DbgFileName ) { UpnpDisplayFileAndLine( InfoFileHnd, DbgFileName, DbgLineNo );} vfprintf( InfoFileHnd, FmtStr, ArgList ); fflush( InfoFileHnd );} } va_end( ArgList ); ithread_mutex_unlock( &GlobalDebugMutex );}
int TimerThreadInit(TimerThread *timer, ThreadPool *tp) { int rc = 0; ThreadPoolJob timerThreadWorker; assert( timer != NULL ); assert( tp != NULL ); if( ( timer == NULL ) || ( tp == NULL ) ) { return EINVAL; } rc += ithread_mutex_init( &timer->mutex, NULL ); assert( rc == 0 ); rc += ithread_mutex_lock( &timer->mutex ); assert( rc == 0 ); rc += ithread_cond_init( &timer->condition, NULL ); assert( rc == 0 ); rc += FreeListInit( &timer->freeEvents, sizeof( TimerEvent ), 100 ); assert( rc == 0 ); timer->shutdown = 0; timer->tp = tp; timer->lastEventId = 0; rc += ListInit( &timer->eventQ, NULL, NULL ); assert( rc == 0 ); if( rc != 0 ) { rc = EAGAIN; } else { TPJobInit( &timerThreadWorker, TimerThreadWorker, timer ); TPJobSetPriority( &timerThreadWorker, HIGH_PRIORITY ); rc = ThreadPoolAddPersistent( tp, &timerThreadWorker, NULL ); } ithread_mutex_unlock( &timer->mutex ); if( rc != 0 ) { ithread_cond_destroy( &timer->condition ); ithread_mutex_destroy( &timer->mutex ); FreeListDestroy( &timer->freeEvents ); ListDestroy( &timer->eventQ, 0 ); } return rc; }
/*! * \brief Copy the contents of the global XML document into the local output * parameter. */ static void alias_grab( /*! [out] XML alias object. */ struct xml_alias_t *alias) { ithread_mutex_lock(&gWebMutex); assert(is_valid_alias(&gAliasDoc)); memcpy(alias, &gAliasDoc, sizeof(struct xml_alias_t)); *alias->ct = *alias->ct + 1; ithread_mutex_unlock(&gWebMutex); }
/***************************************************************************** * Log_Print *****************************************************************************/ int Log_Print (Log_Level level, const char* msg) { if (Log_IsActivated (level) && msg) { ithread_mutex_lock (&g_log_mutex); gPrintFun (level, msg); ithread_mutex_unlock (&g_log_mutex); } return 0; }
static int upnp_client_event_handler(Upnp_EventType type, void *event, void *cookie) { struct Upnp_Discovery *devent = event; /* ignore devices other than the camera */ switch (type) { case UPNP_DISCOVERY_ADVERTISEMENT_ALIVE: case UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE: case UPNP_DISCOVERY_SEARCH_RESULT: if (strcmp(devent->ServiceType, CAMERA_SERVICE_NAME) != 0) return 0; break; default: ; } switch (type) { case UPNP_DISCOVERY_SEARCH_TIMEOUT: ithread_mutex_lock(&state_mutex); discovery_timeout = 1; ithread_cond_signal(&state_cond); ithread_mutex_unlock(&state_mutex); break; case UPNP_DISCOVERY_ADVERTISEMENT_ALIVE: case UPNP_DISCOVERY_SEARCH_RESULT: printf("discovery event: %d\n", type); ithread_mutex_lock(&state_mutex); if (strcmp_null(camera_url, devent->Location) != 0) { free(camera_url); camera_url = strdup(devent->Location); ithread_cond_signal(&state_cond); } ithread_mutex_unlock(&state_mutex); break; case UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE: fprintf(stderr, "FIXME: camera disconnected\n"); break; default: fprintf(stderr, "unhandled client event: %d, %p, %p\n", type, event, cookie); } return 0; }
/******************************************************************************** * TvCtrlPointVerifyTimeouts * * Description: * Checks the advertisement each device * in the global device list. If an advertisement expires, * the device is removed from the list. If an advertisement is about to * expire, a search request is sent for that device. * * Parameters: * incr -- The increment to subtract from the timeouts each time the * function is called. * ********************************************************************************/ void TvCtrlPointVerifyTimeouts( int incr ) { struct TvDeviceNode *prevdevnode, *curdevnode; int ret; ithread_mutex_lock( &DeviceListMutex ); prevdevnode = NULL; curdevnode = GlobalDeviceList; while( curdevnode ) { curdevnode->device.AdvrTimeOut -= incr; //SampleUtil_Print("Advertisement Timeout: %d\n", curdevnode->device.AdvrTimeOut); if( curdevnode->device.AdvrTimeOut <= 0 ) { /* This advertisement has expired, so we should remove the device from the list */ if( GlobalDeviceList == curdevnode ) GlobalDeviceList = curdevnode->next; else prevdevnode->next = curdevnode->next; TvCtrlPointDeleteNode( curdevnode ); if( prevdevnode ) curdevnode = prevdevnode->next; else curdevnode = GlobalDeviceList; } else { if( curdevnode->device.AdvrTimeOut < 2 * incr ) { /* This advertisement is about to expire, so send out a search request for this device UDN to try to renew */ ret = UpnpSearchAsync( ctrlpt_handle, incr, curdevnode->device.UDN, NULL ); if( ret != UPNP_E_SUCCESS ) SampleUtil_Print ( "Error sending search request for Device UDN: %s -- err = %d", curdevnode->device.UDN, ret ); } prevdevnode = curdevnode; curdevnode = curdevnode->next; } } ithread_mutex_unlock( &DeviceListMutex ); }
/******************************************************************************** * TvCtrlPointSendAction * * Description: * Send an Action request to the specified service of a device. * * Parameters: * service -- The service * devnum -- The number of the device (order in the list, * starting with 1) * actionname -- The name of the action. * param_name -- An array of parameter names * param_val -- The corresponding parameter values * param_count -- The number of parameters * ********************************************************************************/ int TvCtrlPointSendAction( int service, int devnum, const char *actionname, const char **param_name, char **param_val, int param_count) { struct TvDeviceNode *devnode; IXML_Document *actionNode = NULL; int rc = TV_SUCCESS; int param; ithread_mutex_lock(&DeviceListMutex); rc = TvCtrlPointGetDevice(devnum, &devnode); if (TV_SUCCESS == rc) { if (0 == param_count) { actionNode = UpnpMakeAction(actionname, TvServiceType[service], 0, NULL); } else { for (param = 0; param < param_count; param++) { if (UpnpAddToAction (&actionNode, actionname, TvServiceType[service], param_name[param], param_val[param]) != UPNP_E_SUCCESS) { SampleUtil_Print ("ERROR: TvCtrlPointSendAction: Trying to add action param\n"); /*return -1; // TBD - BAD! leaves mutex locked */ } } } rc = UpnpSendActionAsync(ctrlpt_handle, devnode->device. TvService[service].ControlURL, TvServiceType[service], NULL, actionNode, TvCtrlPointCallbackEventHandler, NULL); if (rc != UPNP_E_SUCCESS) { SampleUtil_Print("Error in UpnpSendActionAsync -- %d\n", rc); rc = TV_ERROR; } } ithread_mutex_unlock(&DeviceListMutex); if (actionNode) ixmlDocument_free(actionNode); return rc; }
/************************************************************************ * Function: TimerThreadShutdown * * Description: * Shutdown the timer thread * Events scheduled in the future will NOT be run. * Timer thread should be shutdown BEFORE it's associated * thread pool. * Returns: * returns 0 if succesfull, * nonzero otherwise. * Always returns 0. ***********************************************************************/ int TimerThreadShutdown( TimerThread * timer ) { ListNode *tempNode2 = NULL; ListNode *tempNode = NULL; assert( timer != NULL ); if( timer == NULL ) { return EINVAL; } ithread_mutex_lock( &timer->mutex ); timer->shutdown = 1; tempNode = ListHead( &timer->eventQ ); //Delete nodes in Q //call registered free function //on argument while( tempNode != NULL ) { TimerEvent *temp = ( TimerEvent * ) tempNode->item; tempNode2 = ListNext( &timer->eventQ, tempNode ); ListDelNode( &timer->eventQ, tempNode, 0 ); if( temp->job.free_func ) { temp->job.free_func( temp->job.arg ); } FreeTimerEvent( timer, temp ); tempNode = tempNode2; } ListDestroy( &timer->eventQ, 0 ); FreeListDestroy( &timer->freeEvents ); ithread_cond_broadcast( &timer->condition ); while( timer->shutdown ) //wait for timer thread to shutdown { ithread_cond_wait( &timer->condition, &timer->mutex ); } ithread_mutex_unlock( &timer->mutex ); //destroy condition while( ithread_cond_destroy( &timer->condition ) != 0 ) { } //destroy mutex while( ithread_mutex_destroy( &timer->mutex ) != 0 ) { } return 0; }
/** * This function makes a pinhole expires as its lease time is reached * * @param data Expiration event. */ void phv6_expiration(void *data) { struct phv6_expirationEvent *event = ( struct phv6_expirationEvent * ) data; ithread_mutex_lock(&DevMutex); event->pinhole->event_id = -1; phv6_deletePinhole(event->pinhole->unique_id); phv6_freeEvent(event); ithread_mutex_unlock(&DevMutex); }
int ThreadPoolGetAttr(ThreadPool *tp, ThreadPoolAttr *out) { if (!tp || !out) return EINVAL; if (!tp->shutdown) ithread_mutex_lock(&tp->mutex); *out = tp->attr; if (!tp->shutdown) ithread_mutex_unlock(&tp->mutex); return 0; }
/*! * \brief Increment the volume. Read the current volume from the state table, * add the increment, and then change the volume. */ static int IncrementVolume( /*! [in] The increment by which to change the volume. */ int incr, /*! [in] Action request document. */ IXML_Document * in, /*! [out] Action result document. */ IXML_Document ** out, /*! [out] Error string in case action was unsuccessful. */ const char **errorString) { int curvolume; int newvolume; const char *actionName = NULL; char value[TV_MAX_VAL_LEN]; if (incr > 0) { actionName = "IncreaseVolume"; } else { actionName = "DecreaseVolume"; } ithread_mutex_lock(&TVDevMutex); curvolume = atoi(tv_service_table[TV_SERVICE_CONTROL].VariableStrVal [TV_CONTROL_VOLUME]); ithread_mutex_unlock(&TVDevMutex); newvolume = curvolume + incr; if (newvolume < MIN_VOLUME || newvolume > MAX_VOLUME) { SampleUtil_Print("error: can't change to volume %d\n", newvolume); (*errorString) = "Invalid Volume"; return UPNP_E_INVALID_PARAM; } /* Vendor-specific code to set the volume goes here. */ sprintf(value, "%d", newvolume); if (TvDeviceSetServiceTableVar(TV_SERVICE_CONTROL, TV_CONTROL_VOLUME, value)) { if (UpnpAddToActionResponse(out, actionName, TvServiceType[TV_SERVICE_CONTROL], "Volume", value) != UPNP_E_SUCCESS) { (*out) = NULL; (*errorString) = "Internal Error"; return UPNP_E_INTERNAL_ERROR; } return UPNP_E_SUCCESS; } else { (*errorString) = "Internal Error"; return UPNP_E_INTERNAL_ERROR; } in = in; }
void upnp_context_free_callbacks(upnp_igd_context *igd_ctxt) { upnp_igd_callback_event_node *node; if(igd_ctxt->callback_fct != NULL) { ithread_mutex_lock(&igd_ctxt->callback_mutex); while(igd_ctxt->callback_events != NULL) { node = igd_ctxt->callback_events; igd_ctxt->callback_events = node->next; free(node); } ithread_mutex_unlock(&igd_ctxt->callback_mutex); } }
DBG_STATIC int transport_notify_subscription(void) { ithread_mutex_lock(&transport_mutex); output_update_status(); transport_set_var(TRANSPORT_VAR_LAST_CHANGE, transport_get_state_lastchange()); ithread_mutex_unlock(&transport_mutex); return 0; }
/*! * \brief Increment the brightness. Read the current brightness from the state * table, add the increment, and then change the brightness. */ static int IncrementBrightness( /*! [in] The increment by which to change the brightness. */ int incr, /*! [in] action request document. */ IXML_Document * in, /*! [out] action result document. */ IXML_Document ** out, /*! [out] errorString (in case action was unsuccessful). */ const char **errorString) { int curbrightness; int newbrightness; const char *actionName = NULL; char value[TV_MAX_VAL_LEN]; if (incr > 0) { actionName = "IncreaseBrightness"; } else { actionName = "DecreaseBrightness"; } ithread_mutex_lock(&TVDevMutex); curbrightness = atoi(tv_service_table[TV_SERVICE_PICTURE].VariableStrVal [TV_PICTURE_BRIGHTNESS]); ithread_mutex_unlock(&TVDevMutex); newbrightness = curbrightness + incr; if (newbrightness < MIN_BRIGHTNESS || newbrightness > MAX_BRIGHTNESS) { SampleUtil_Print("error: can't change to brightness %d\n", newbrightness); (*errorString) = "Invalid Brightness"; return UPNP_E_INVALID_PARAM; } /* Vendor-specific code to set the channel goes here. */ sprintf(value, "%d", newbrightness); if (TvDeviceSetServiceTableVar(TV_SERVICE_PICTURE, TV_PICTURE_BRIGHTNESS, value)) { if (UpnpAddToActionResponse(out, actionName, TvServiceType[TV_SERVICE_PICTURE], "Brightness", value) != UPNP_E_SUCCESS) { (*out) = NULL; (*errorString) = "Internal Error"; return UPNP_E_INTERNAL_ERROR; } return UPNP_E_SUCCESS; } else { (*errorString) = "Internal Error"; return UPNP_E_INTERNAL_ERROR; } in = in; }
/******************************************************************************** * upnp_igd_handle_send_action * * Description: * Function called when a variable is grabbed * * Parameters: * igd_ctxt -- The upnp igd context * controlURL -- The control url used for the update * varName -- The variable name * varValue -- The value of the variable * ********************************************************************************/ void upnp_igd_handle_send_action(upnp_igd_context* igd_ctxt, const char *controlURL, IXML_Document *action, IXML_Document *result) { upnp_igd_device_node *tmpdevnode; int service; IXML_Element *variable; IXML_NodeList *variables; long unsigned int length1; int j; char *tmpstate = NULL; char variable_name[sizeof("New") + IGD_MAX_VAR_LEN]; ithread_mutex_lock(&igd_ctxt->devices_mutex); tmpdevnode = igd_ctxt->devices; while (tmpdevnode) { for (service = 0; service < IGD_SERVICE_SERVCOUNT; service++) { if (strcmp(tmpdevnode->device.services[service].control_url, controlURL) == 0) { for (j = 0; j < IGDVarCount[service]; j++) { // Build the element name from the variable strcpy(variable_name, "New"); strcat(variable_name, IGDVarName[service][j]); variables = ixmlDocument_getElementsByTagName(result, variable_name); /* If a match is found, extract * the value, and update the state table */ if (variables) { length1 = ixmlNodeList_length(variables); if (length1) { variable = (IXML_Element *) ixmlNodeList_item(variables, 0); tmpstate = upnp_igd_get_element_value(igd_ctxt, variable); if (tmpstate) { if(strcmp(tmpdevnode->device.services[service].variables[j], tmpstate)) { upnp_igd_strncpy(tmpdevnode->device.services[service].variables[j], tmpstate, IGD_MAX_VAR_LEN); upnp_igd_var_updated(igd_ctxt, tmpdevnode, service, j, tmpdevnode->device.services[service].variables[j]); } } if (tmpstate) { free(tmpstate); } tmpstate = NULL; } ixmlNodeList_free(variables); variables = NULL; } } break; } } tmpdevnode = tmpdevnode->next; } ithread_mutex_unlock(&igd_ctxt->devices_mutex); }
DBG_STATIC int get_position_info(struct action_event *event) { int rc = -1; if (upnp_obtain_instanceid(event, NULL)) { upnp_set_error(event, UPNP_TRANSPORT_E_INVALID_IID, "ID non-zero invalid"); return -1; } ithread_mutex_lock(&transport_mutex); // Calls back into transport to set vars output_update_position(); ithread_mutex_unlock(&transport_mutex); rc = upnp_append_variable(event, TRANSPORT_VAR_CUR_TRACK, "Track"); if (rc) goto out; rc = upnp_append_variable(event, TRANSPORT_VAR_CUR_TRACK_DUR, "TrackDuration"); if (rc) goto out; rc = upnp_append_variable(event, TRANSPORT_VAR_CUR_TRACK_META, "TrackMetaData"); if (rc) goto out; rc = upnp_append_variable(event, TRANSPORT_VAR_CUR_TRACK_URI, "TrackURI"); if (rc) goto out; rc = upnp_append_variable(event, TRANSPORT_VAR_REL_TIME_POS, "RelTime"); if (rc) goto out; rc = upnp_append_variable(event, TRANSPORT_VAR_ABS_TIME_POS, "AbsTime"); if (rc) goto out; rc = upnp_append_variable(event, TRANSPORT_VAR_REL_CTR_POS, "RelCount"); if (rc) goto out; rc = upnp_append_variable(event, TRANSPORT_VAR_ABS_CTR_POS, "AbsCount"); if (rc) goto out; out: return rc; }
DBG_STATIC int xplay(struct action_event *event) { int rc = 0; if (upnp_obtain_instanceid(event, NULL)) { upnp_set_error(event, UPNP_TRANSPORT_E_INVALID_IID, "ID non-zero invalid"); return -1; } // Check MPD connection if (check_mpd_connection(TRUE) == STATUS_FAIL) return -1; ithread_mutex_lock(&transport_mutex); switch (transport_state) { case TRANSPORT_PLAYING: // Set TransportPlaySpeed to '1' break; case TRANSPORT_STOPPED: case TRANSPORT_PAUSED_PLAYBACK: if (output_play()) { upnp_set_error(event, UPNP_TRANSPORT_E_NO_CONTENTS, "Player Start failed"); rc = -1; } else { transport_state = TRANSPORT_PLAYING; transport_change_var(event, TRANSPORT_VAR_TRANSPORT_STATE, "PLAYING"); } // Set TransportPlaySpeed to '1' break; case TRANSPORT_NO_MEDIA_PRESENT: case TRANSPORT_TRANSITIONING: /* action not allowed in these states - error 701 */ upnp_set_error(event, UPNP_TRANSPORT_E_TRANSITION_NA, "Transition not allowed"); rc = -1; break; } ithread_mutex_unlock(&transport_mutex); return rc; }
/*----------------------------------------------------------------------------*/ void FlushActionList(struct sMR *Device) { struct sAction *p; ithread_mutex_lock(&Device->ActionsMutex); p = Device->Actions; while (Device->Actions) { p = Device->Actions; Device->Actions = Device->Actions->Next;
void web_server_destroy(void) { if (bWebServerState == WEB_SERVER_ENABLED) { membuffer_destroy(&gDocumentRootDir); alias_release(&gAliasDoc); ithread_mutex_lock(&gWebMutex); memset(&gAliasDoc, 0, sizeof(struct xml_alias_t)); ithread_mutex_unlock(&gWebMutex); ithread_mutex_destroy(&gWebMutex); bWebServerState = WEB_SERVER_DISABLED; } }
void upnp_igd_print(upnp_igd_context *igd_ctxt, upnp_igd_print_level level, const char *fmt, ...) { va_list ap; /* Protect both the display and the static buffer with the mutex */ ithread_mutex_lock(&igd_ctxt->print_mutex); va_start(ap, fmt); if (igd_ctxt->print_fct) { igd_ctxt->print_fct(igd_ctxt->cookie, level, fmt, ap); } va_end(ap); ithread_mutex_unlock(&igd_ctxt->print_mutex); }
int ThreadPoolAdd(ThreadPool *tp, ThreadPoolJob *job, int *jobId) { int rc = EOUTOFMEM; int tempId = -1; long totalJobs; ThreadPoolJob *temp = NULL; if (!tp || !job) return EINVAL; ithread_mutex_lock(&tp->mutex); totalJobs = tp->highJobQ.size + tp->lowJobQ.size + tp->medJobQ.size; if (totalJobs >= tp->attr.maxJobsTotal) { fprintf(stderr, "total jobs = %ld, too many jobs", totalJobs); goto exit_function; } if (!jobId) jobId = &tempId; *jobId = INVALID_JOB_ID; temp = CreateThreadPoolJob(job, tp->lastJobId, tp); if (!temp) goto exit_function; switch (job->priority) { case HIGH_PRIORITY: if (ListAddTail(&tp->highJobQ, temp)) rc = 0; break; case MED_PRIORITY: if (ListAddTail(&tp->medJobQ, temp)) rc = 0; break; default: if (ListAddTail(&tp->lowJobQ, temp)) rc = 0; } /* AddWorker if appropriate */ AddWorker(tp); /* Notify a waiting thread */ if (rc == 0) ithread_cond_signal(&tp->condition); else FreeThreadPoolJob(tp, temp); *jobId = tp->lastJobId++; exit_function: ithread_mutex_unlock(&tp->mutex); return rc; }
int IncrementChannel(int incr, IN IXML_Document * in, IXML_Document ** out, const char **errorString) { int curchannel; int newchannel; const char *actionName = NULL; char value[TV_MAX_VAL_LEN]; if (incr > 0) { actionName = "IncreaseChannel"; } else { actionName = "DecreaseChannel"; } ithread_mutex_lock(&TVDevMutex); curchannel = atoi(tv_service_table[TV_SERVICE_CONTROL].VariableStrVal [TV_CONTROL_CHANNEL]); ithread_mutex_unlock(&TVDevMutex); newchannel = curchannel + incr; if (newchannel < MIN_CHANNEL || newchannel > MAX_CHANNEL) { SampleUtil_Print("error: can't change to channel %d\n", newchannel); (*errorString) = "Invalid Channel"; return UPNP_E_INVALID_PARAM; } /* Vendor-specific code to set the channel goes here. */ sprintf(value, "%d", newchannel); if (TvDeviceSetServiceTableVar(TV_SERVICE_CONTROL, TV_CONTROL_CHANNEL, value)) { if (UpnpAddToActionResponse(out, actionName, TvServiceType[TV_SERVICE_CONTROL], "Channel", value) != UPNP_E_SUCCESS) { (*out) = NULL; (*errorString) = "Internal Error"; return UPNP_E_INTERNAL_ERROR; } return UPNP_E_SUCCESS; } else { (*errorString) = "Internal Error"; return UPNP_E_INTERNAL_ERROR; } in = in; }
/**************************************************************************** * Function: ThreadPoolSetAttr * * Description: * Sets the attributes for the thread pool. * Only affects future calculations. * Parameters: * tp - valid thread pool pointer * attr - pointer to attributes, null sets attributes to default. * Returns: * 0 on success, nonzero on failure * Returns INVALID_POLICY if policy can not be set. *****************************************************************************/ int ThreadPoolSetAttr( ThreadPool *tp, ThreadPoolAttr *attr ) { int retCode = 0; ThreadPoolAttr temp; int i = 0; assert( tp != NULL ); if( tp == NULL ) { return EINVAL; } ithread_mutex_lock( &tp->mutex ); if( attr != NULL ) { temp = ( *attr ); } else { TPAttrInit( &temp ); } if( SetPolicyType( temp.schedPolicy ) != 0 ) { ithread_mutex_unlock( &tp->mutex ); return INVALID_POLICY; } tp->attr = ( temp ); // add threads if( tp->totalThreads < tp->attr.minThreads ) { for( i = tp->totalThreads; i < tp->attr.minThreads; i++ ) { if( ( retCode = CreateWorker( tp ) ) != 0 ) { break; } } } // signal changes ithread_cond_signal( &tp->condition ); ithread_mutex_unlock( &tp->mutex ); if( retCode != 0 ) { // clean up if the min threads could not be created ThreadPoolShutdown( tp ); } return retCode; }
int ThreadPoolAddPersistent(ThreadPool *tp, ThreadPoolJob *job, int *jobId) { int ret = 0; int tempId = -1; ThreadPoolJob *temp = NULL; if (!tp || !job) { return EINVAL; } if (!jobId) { jobId = &tempId; } *jobId = INVALID_JOB_ID; ithread_mutex_lock(&tp->mutex); /* Create A worker if less than max threads running */ if (tp->totalThreads < tp->attr.maxThreads) { CreateWorker(tp); } else { /* if there is more than one worker thread * available then schedule job, otherwise fail */ if (tp->totalThreads - tp->persistentThreads - 1 == 0) { ret = EMAXTHREADS; goto exit_function; } } temp = CreateThreadPoolJob(job, tp->lastJobId, tp); if (!temp) { ret = EOUTOFMEM; goto exit_function; } tp->persistentJob = temp; /* Notify a waiting thread */ ithread_cond_signal(&tp->condition); /* wait until long job has been picked up */ while (tp->persistentJob) ithread_cond_wait(&tp->start_and_shutdown, &tp->mutex); *jobId = tp->lastJobId++; exit_function: ithread_mutex_unlock(&tp->mutex); return ret; }
int TvDeviceHandleGetVarRequest(UpnpStateVarRequest *cgv_event) { unsigned int i = 0; int j = 0; int getvar_succeeded = 0; UpnpStateVarRequest_set_CurrentVal(cgv_event, NULL); ithread_mutex_lock(&TVDevMutex); for (i = 0; i < TV_SERVICE_SERVCOUNT; i++) { /* check udn and service id */ const char *devUDN = UpnpString_get_String(UpnpStateVarRequest_get_DevUDN(cgv_event)); const char *serviceID = UpnpString_get_String(UpnpStateVarRequest_get_ServiceID(cgv_event)); if (strcmp(devUDN, tv_service_table[i].UDN) == 0 && strcmp(serviceID, tv_service_table[i].ServiceId) == 0) { /* check variable name */ for (j = 0; j < tv_service_table[i].VariableCount; j++) { const char *stateVarName = UpnpString_get_String( UpnpStateVarRequest_get_StateVarName(cgv_event)); if (strcmp(stateVarName, tv_service_table[i].VariableName[j]) == 0) { getvar_succeeded = 1; UpnpStateVarRequest_set_CurrentVal(cgv_event, tv_service_table[i].VariableStrVal[j]); break; } } } } if (getvar_succeeded) { UpnpStateVarRequest_set_ErrCode(cgv_event, UPNP_E_SUCCESS); } else { SampleUtil_Print("Error in UPNP_CONTROL_GET_VAR_REQUEST callback:\n" " Unknown variable name = %s\n", UpnpString_get_String(UpnpStateVarRequest_get_StateVarName(cgv_event))); UpnpStateVarRequest_set_ErrCode(cgv_event, 404); UpnpStateVarRequest_strcpy_ErrStr(cgv_event, "Invalid Variable"); } ithread_mutex_unlock(&TVDevMutex); return UpnpStateVarRequest_get_ErrCode(cgv_event) == UPNP_E_SUCCESS; }
void upnp_append_variable(struct action_event *event, int varnum, const char *paramname) { const char *value; struct service *service = event->service; assert(event != NULL); assert(paramname != NULL); ithread_mutex_lock(service->service_mutex); value = VariableContainer_get(service->variable_container, varnum, NULL); assert(value != NULL); // triggers on invalid variable. upnp_add_response(event, paramname, value); ithread_mutex_unlock(service->service_mutex); }
/******************************************************************************** * upnp_igd_verify_timeouts * * Description: * Check all the device for refreshing which ones are close to timeout. * * Parameters: * igd_ctxt -- The upnp igd context * incr -- Number of second before next check * ********************************************************************************/ void upnp_igd_verify_timeouts(upnp_igd_context *igd_ctxt, int incr) { upnp_igd_device_node *prevdevnode, *curdevnode; int ret; ithread_mutex_lock(&igd_ctxt->devices_mutex); prevdevnode = NULL; curdevnode = igd_ctxt->devices; while (curdevnode) { if(curdevnode->device.advr_time_out > igd_ctxt->max_adv_timeout) { curdevnode->device.advr_time_out = igd_ctxt->max_adv_timeout; } curdevnode->device.advr_time_out -= incr; upnp_igd_print(igd_ctxt, UPNP_IGD_DEBUG, "IGD device: %s[%s] | Advertisement Timeout: %d", curdevnode->device.friendly_name, curdevnode->device.udn, curdevnode->device.advr_time_out); if (curdevnode->device.advr_time_out <= 0) { /* This advertisement has expired, so we should remove the device * from the list */ if (igd_ctxt->devices == curdevnode) igd_ctxt->devices = curdevnode->next; else prevdevnode->next = curdevnode->next; upnp_igd_delete_node(igd_ctxt, curdevnode); if (prevdevnode) curdevnode = prevdevnode->next; else curdevnode = igd_ctxt->devices; } else { if (curdevnode->device.advr_time_out < 2 * incr) { /* This advertisement is about to expire, so * send out a search request for this device * UDN to try to renew */ ret = UpnpSearchAsync(igd_ctxt->upnp_handle, incr, curdevnode->device.udn, igd_ctxt); if (ret != UPNP_E_SUCCESS) upnp_igd_print(igd_ctxt, UPNP_IGD_ERROR, "Error sending search request for Device UDN: %s -- err = %d", curdevnode->device.udn, ret); } prevdevnode = curdevnode; curdevnode = curdevnode->next; } } ithread_mutex_unlock(&igd_ctxt->devices_mutex); }
int web_server_set_alias(const char *alias_name, const char *alias_content, size_t alias_content_length, time_t last_modified) { int ret_code; struct xml_alias_t alias; alias_release(&gAliasDoc); if (alias_name == NULL) { /* don't serve aliased doc anymore */ return 0; } assert(alias_content != NULL); membuffer_init(&alias.doc); membuffer_init(&alias.name); alias.ct = NULL; do { /* insert leading /, if missing */ if (*alias_name != '/') if (membuffer_assign_str(&alias.name, "/") != 0) break; /* error; out of mem */ ret_code = membuffer_append_str(&alias.name, alias_name); if (ret_code != 0) break; /* error */ if ((alias.ct = (int *)malloc(sizeof(int))) == NULL) break; /* error */ *alias.ct = 1; membuffer_attach(&alias.doc, (char *)alias_content, alias_content_length); alias.last_modified = last_modified; /* save in module var */ ithread_mutex_lock(&gWebMutex); gAliasDoc = alias; ithread_mutex_unlock(&gWebMutex); return 0; } while (FALSE); /* error handler */ /* free temp alias */ membuffer_destroy(&alias.name); membuffer_destroy(&alias.doc); free(alias.ct); return UPNP_E_OUTOF_MEMORY; }
int ThreadPoolGetStats( ThreadPool *tp, ThreadPoolStats *stats ) { assert(tp != NULL); assert(stats != NULL); if (tp == NULL || stats == NULL) { return EINVAL; } //if not shutdown then acquire mutex if (!tp->shutdown) { ithread_mutex_lock(&tp->mutex); } *stats = tp->stats; if (stats->totalJobsHQ > 0) { stats->avgWaitHQ = stats->totalTimeHQ / stats->totalJobsHQ; } else { stats->avgWaitHQ = 0; } if( stats->totalJobsMQ > 0 ) { stats->avgWaitMQ = stats->totalTimeMQ / stats->totalJobsMQ; } else { stats->avgWaitMQ = 0; } if( stats->totalJobsLQ > 0 ) { stats->avgWaitLQ = stats->totalTimeLQ / stats->totalJobsLQ; } else { stats->avgWaitLQ = 0; } stats->totalThreads = tp->totalThreads; stats->persistentThreads = tp->persistentThreads; stats->currentJobsHQ = ListSize( &tp->highJobQ ); stats->currentJobsLQ = ListSize( &tp->lowJobQ ); stats->currentJobsMQ = ListSize( &tp->medJobQ ); //if not shutdown then release mutex if( !tp->shutdown ) { ithread_mutex_unlock( &tp->mutex ); } return 0; }
int AddMiniServerInterface(const char *ip, int *iface, uint16_t *listen_port4) { int i; int error; ithread_mutex_lock(&gMiniServerMutex); for (i = 0; i < MAX_NETWORK_INTERFACES; ++i) { if (gMiniSocket->miniServerSock4[i] == INVALID_SOCKET) break; } if (i == MAX_NETWORK_INTERFACES) { UpnpPrintf(UPNP_CRITICAL, MSERV, __FILE__, __LINE__, "AddMiniServerInterface: no free interface slots"); ithread_mutex_unlock(&gMiniServerMutex); return UPNP_E_OUTOF_SOCKET; } error = get_miniserver_sockets(gMiniSocket, ip, i, *listen_port4); if (error != UPNP_E_SUCCESS) { UpnpPrintf(UPNP_CRITICAL, MSERV, __FILE__, __LINE__, "AddMiniServerInterface: get_miniserver_sockets failed with error %d", error); ithread_mutex_unlock(&gMiniServerMutex); return error; } error = get_ssdp_sockets(gMiniSocket, ip, i); if (error != UPNP_E_SUCCESS) { UpnpPrintf(UPNP_CRITICAL, MSERV, __FILE__, __LINE__, "AddMiniServerInterface: get_ssdp_sockets failed with error %d", error); ithread_mutex_unlock(&gMiniServerMutex); return error; } *listen_port4 = gMiniSocket->miniServerPort4[i]; *iface = i; ithread_mutex_unlock(&gMiniServerMutex); wake_miniserver(); UpnpPrintf(UPNP_INFO, MSERV, __FILE__, __LINE__, "AddMiniServerInterface: %s:%d added successfully to slot %d", ip, *listen_port4, i); return UPNP_E_SUCCESS; }