/***************************************************************************** * _ObjectClass_Lock *****************************************************************************/ int _ObjectClass_Lock() { if (! g_mutex_initialized) { ithread_mutexattr_t attr; ithread_mutexattr_init (&attr); ithread_mutexattr_setkind_np (&attr, ITHREAD_MUTEX_RECURSIVE_NP ); ithread_mutex_init (&g_class_mutex, &attr); ithread_mutexattr_destroy (&attr); g_mutex_initialized = true; } return pthread_mutex_lock (&g_class_mutex); }
/******************************************************************************** * SampleUtil_Initialize * * Description: * Initializes the sample util. Must be called before any sample util * functions. May be called multiple times. * * Parameters: * print_function - print function to use in SampleUtil_Print * ********************************************************************************/ int SampleUtil_Initialize( print_string print_function ) { if( initialize ) { ithread_mutexattr_t attr; gPrintFun = print_function; ithread_mutexattr_init( &attr ); ithread_mutexattr_setkind_np( &attr, ITHREAD_MUTEX_RECURSIVE_NP ); ithread_mutex_init( &display_mutex, &attr ); ithread_mutexattr_destroy( &attr ); initialize = 0; } return UPNP_E_SUCCESS; }
int Log_Initialize (Log_PrintFunction print_function ) { if (! g_initialized) { ithread_mutexattr_t attr; ithread_mutexattr_init (&attr); ithread_mutexattr_setkind_np (&attr, ITHREAD_MUTEX_RECURSIVE_NP); ithread_mutex_init (&g_log_mutex, &attr); ithread_mutexattr_destroy (&attr); g_initialized = true; } gPrintFun = print_function; return 0; }
int SampleUtil_Initialize(print_string print_function) { if (initialize_init) { ithread_mutexattr_t attr; ithread_mutexattr_init(&attr); ithread_mutexattr_setkind_np(&attr, ITHREAD_MUTEX_RECURSIVE_NP); ithread_mutex_init(&display_mutex, &attr); ithread_mutexattr_destroy(&attr); /* To shut up valgrind mutex warning. */ ithread_mutex_lock(&display_mutex); gPrintFun = print_function; ithread_mutex_unlock(&display_mutex); /* Finished initializing. */ initialize_init = 0; } return UPNP_E_SUCCESS; }
/******************************************************************************** * upnp_igd_create * * Description: * Create and return uPnP IGD context if there is no error otherwise * NULL. * * Parameters: * cb_fct -- The function to call back for each events * print_fct -- The function used for print logs * cookie -- The cookie pass in cb_fct or print_fct * ********************************************************************************/ upnp_igd_context* upnp_igd_create(upnp_igd_callback_function cb_fct, upnp_igd_print_function print_fct, const char *address, void *cookie) { int ret; unsigned short port = 0; const char *ip_address = address; upnp_igd_context *igd_ctxt = (upnp_igd_context*)malloc(sizeof(upnp_igd_context)); igd_ctxt->devices = NULL; igd_ctxt->callback_fct = cb_fct; igd_ctxt->callback_events = NULL; igd_ctxt->print_fct = print_fct; igd_ctxt->cookie = cookie; igd_ctxt->max_adv_timeout = 60*3; igd_ctxt->timer_timeout = igd_ctxt->max_adv_timeout/2; igd_ctxt->upnp_handle = -1; igd_ctxt->client_count = 0; igd_ctxt->timer_thread = (ithread_t)NULL; /* Initialize mutex */ { ithread_mutexattr_t attr; ithread_mutexattr_init(&attr); ithread_mutexattr_setkind_np(&attr, ITHREAD_MUTEX_RECURSIVE_NP); ithread_mutex_init(&igd_ctxt->mutex, &attr); ithread_mutexattr_destroy(&attr); } /* Initialize print mutex */ { ithread_mutexattr_t attr; ithread_mutexattr_init(&attr); ithread_mutexattr_setkind_np(&attr, ITHREAD_MUTEX_RECURSIVE_NP); ithread_mutex_init(&igd_ctxt->print_mutex, &attr); ithread_mutexattr_destroy(&attr); } /* Initialize callback mutex */ { ithread_mutexattr_t attr; ithread_mutexattr_init(&attr); ithread_mutexattr_setkind_np(&attr, ITHREAD_MUTEX_RECURSIVE_NP); ithread_mutex_init(&igd_ctxt->callback_mutex, &attr); ithread_mutexattr_destroy(&attr); } /* Initialize device mutex */ { ithread_mutexattr_t attr; ithread_mutexattr_init(&attr); ithread_mutexattr_setkind_np(&attr, ITHREAD_MUTEX_RECURSIVE_NP); ithread_mutex_init(&igd_ctxt->devices_mutex, &attr); ithread_mutexattr_destroy(&attr); } /* Initialize timer stuff */ { ithread_mutexattr_t attr; ithread_mutexattr_init(&attr); ithread_mutexattr_setkind_np(&attr, ITHREAD_MUTEX_FAST_NP); ithread_mutex_init(&igd_ctxt->timer_mutex, &attr); ithread_mutexattr_destroy(&attr); ithread_cond_init(&igd_ctxt->timer_cond, NULL); } /* Initialize client stuff */ { ithread_mutexattr_t attr; ithread_mutexattr_init(&attr); ithread_mutexattr_setkind_np(&attr, ITHREAD_MUTEX_RECURSIVE_NP); ithread_mutex_init(&igd_ctxt->client_mutex, &attr); ithread_mutexattr_destroy(&attr); ithread_cond_init(&igd_ctxt->client_cond, NULL); } upnp_igd_print(igd_ctxt, UPNP_IGD_DEBUG, "Initializing uPnP IGD with ipaddress:%s port:%u", ip_address ? ip_address : "{NULL}", port); ret = UpnpInit(ip_address, port); if (ret != UPNP_E_SUCCESS) { upnp_igd_print(igd_ctxt, UPNP_IGD_ERROR, "UpnpInit() Error: %d", ret); UpnpFinish(); ithread_mutex_destroy(&igd_ctxt->print_mutex); ithread_mutex_destroy(&igd_ctxt->devices_mutex); ithread_mutex_destroy(&igd_ctxt->timer_mutex); ithread_cond_destroy(&igd_ctxt->timer_cond); ithread_mutex_destroy(&igd_ctxt->callback_mutex); ithread_mutex_destroy(&igd_ctxt->client_mutex); ithread_cond_destroy(&igd_ctxt->client_cond); ithread_mutex_destroy(&igd_ctxt->mutex); free(igd_ctxt); return NULL; } if (!ip_address) { ip_address = UpnpGetServerIpAddress(); } if (!port) { port = UpnpGetServerPort(); } upnp_igd_print(igd_ctxt, UPNP_IGD_MESSAGE, "uPnP IGD Initialized ipaddress:%s port:%u", ip_address ? ip_address : "{NULL}", port); return igd_ctxt; }
/****************************************************************************** * BrowseOrSearchAll *****************************************************************************/ static ContentDir_Children* BrowseOrSearchAll (ContentDir* cds, void* result_context, const char* objectId, const char* const criteria) { ContentDir_Children* result = talloc (result_context, ContentDir_Children); if (result == NULL) return NULL; // ----------> PtrArray* objects = PtrArray_Create (result); if (objects == NULL) goto FAIL; // ----------> *result = (ContentDir_Children) { .objects = objects }; #if CONTENT_DIR_HAVE_CHILDREN_MUTEX ithread_mutexattr_t attr; ithread_mutexattr_init (&attr); ithread_mutexattr_setkind_np (&attr, ITHREAD_MUTEX_RECURSIVE_NP); ithread_mutex_init (&result->mutex, &attr); ithread_mutexattr_destroy (&attr); #endif talloc_set_destructor (result, DestroyChildren); // Request all objects Count nb_matched = 0; Count nb_returned = 0; int rc = BrowseOrSearchAction (cds, objects, objectId, criteria, /* starting_index => */ 0, /* requested_count => */ 0, &nb_matched, &nb_returned, objects); if (rc != UPNP_E_SUCCESS) goto FAIL; // ----------> // Loop if missing entries // (this is not normal : "RequestedCount" == 0 means to request // all entries according to ContentDirectory specification). // Note: it is allowed to have nb_matched == 0 if it cannot be // computed by the CDS. int nb_retry = 0; while (PtrArray_GetSize (objects) < nb_matched && nb_retry++ < 2) { Log_Printf (LOG_WARNING, "ContentDir_BrowseId ObjectId=%s : " "got %d results, expected %d. Retry %d ...", objectId, (int) PtrArray_GetSize (objects), (int) nb_matched, nb_retry); // Workaround : request missing entries. rc = BrowseOrSearchAction (cds, objects, objectId, criteria, /* starting_index => */ PtrArray_GetSize (objects), /* requested_count => */ nb_matched - PtrArray_GetSize (objects), &nb_matched, &nb_returned, objects); // Stop if error, or no more results (to prevent infinite loop) if (rc != UPNP_E_SUCCESS || nb_returned == 0) break; // ----------> } return result; FAIL: talloc_free (result); return NULL; }