void logutil_tid_test() { logutil_tid_init(); fprintf(stderr, "ADD %d\n", logutil_tid_add(1, "one")); fprintf(stderr, "ADD %d\n", logutil_tid_add(2, "two")); fprintf(stderr, "REMOVE%d\n", logutil_tid_remove(1)); fprintf(stderr, "ADD %d\n", logutil_tid_add(3, "three")); fprintf(stderr, "ADD %d\n", logutil_tid_add(4, "four")); fprintf(stderr, "LOOKUP 4 '%s'\n", logutil_tid_lookup(4)); fprintf(stderr, "LOOKUP 3 '%s'\n", logutil_tid_lookup(3)); logutil_tid_dump(); }
static void print_tag(LOG_PROPERTIES_T *pLogProperties, char strpid[], size_t szpid) { const char *tag = NULL; if((pLogProperties->g_log_flags & LOG_OUTPUT_PRINT_TAG)) { if((tag = logutil_tid_lookup(pthread_self(), 1)) && tag[0] == '\0') { tag = NULL; } } if((pLogProperties->g_log_flags & LOG_OUTPUT_PRINT_PID) && (pLogProperties->g_log_flags & LOG_OUTPUT_PRINT_TID)) { snprintf(strpid, szpid - 1, "[%d,%"PTHREAD_T_PRINTF"%s%s]", (int) getpid(), ( PTHREAD_SELF_TOINT(pthread_self())), tag ? " - " : "", tag ? tag : ""); } else if(pLogProperties->g_log_flags & LOG_OUTPUT_PRINT_PID) { snprintf(strpid, szpid - 1, "[%d%s%s]", (int) getpid(), tag ? " - " : "", tag ? tag : ""); } else if(pLogProperties->g_log_flags & LOG_OUTPUT_PRINT_TID) { snprintf(strpid, szpid - 1, "[%"PTHREAD_T_PRINTF"%s%s]", PTHREAD_SELF_TOINT(pthread_self()), tag ? " - " : "", tag ? tag : ""); } else if(tag != NULL && tag[0] != '\0') { snprintf(strpid, szpid -1, "[%s] ", tag); } strpid[szpid - 1] = '\0'; }
int srvlisten_startrtsplive(SRV_LISTENER_CFG_T *pListenCfg) { pthread_t ptdRtspLive; pthread_attr_t attrRtspLive; const char *s; int rc = 0; if(!pListenCfg || !pListenCfg->pConnPool || pListenCfg->max <= 0 || !pListenCfg->pCfg || !pListenCfg->pCfg->cfgShared.pRtspSessions || pListenCfg->pCfg->cfgShared.pRtspSessions->max <= 0) { return -1; } if((pListenCfg->netflags & NETIO_FLAG_SSL_TLS) && !netio_ssl_enabled(1)) { LOG(X_ERROR("SSL not enabled")); return -1; } if((s = logutil_tid_lookup(pthread_self(), 0)) && s[0] != '\0') { snprintf(pListenCfg->tid_tag, sizeof(pListenCfg->tid_tag), "%s-rtsp", s); } pthread_attr_init(&attrRtspLive); pthread_attr_setdetachstate(&attrRtspLive, PTHREAD_CREATE_DETACHED); if(pthread_create(&ptdRtspLive, &attrRtspLive, (void *) srvlisten_rtsplive_proc, (void *) pListenCfg) != 0) { LOG(X_ERROR("Unable to create rtsp listener thread")); return -1; } return rc; }
int capture_send_dummy_frames_start(CAP_ASYNC_DESCR_T *pCfg, CAPTURE_STATE_T *pState, STREAMER_STATE_T *prunning, pthread_mutex_t *pmtx) { CAP_SEND_DUMMY_FRAMES_CTXT_T args; const char *s; pthread_t ptd; pthread_attr_t attr; PHTREAD_INIT_ATTR(&attr); memset(&args, 0, sizeof(args)); args.pCfg = pCfg; args.pState = pState; args.prunning = prunning; args.pmtx = pmtx; if((s = logutil_tid_lookup(pthread_self(), 0)) && s[0] != '\0') { snprintf(args.tid_tag, sizeof(args.tid_tag), "%s-capdm", s); } *prunning = STREAMER_STATE_STARTING_THREAD; if(pthread_create(&ptd, &attr, (void *) capture_send_dummy_frames_proc, (void *) &args) != 0) { *prunning = STREAMER_STATE_ERROR; return -1; } while(*args.prunning == STREAMER_STATE_STARTING_THREAD) { usleep(5000); } return 0; }
int stream_monitor_start(STREAM_STATS_MONITOR_T *pMonitor, const char *statfilepath, unsigned int intervalMs) { int rc = 0; pthread_t ptdMonitor; pthread_attr_t attrMonitor; const char *s; MONITOR_START_WRAP_T startWrap; if(!pMonitor) { return -1; } else if(pMonitor->active) { return 0; } if(statfilepath && statfilepath[0] == '\0') { statfilepath = NULL; } pthread_mutex_init(&pMonitor->mtx, NULL); pMonitor->active = 1; pMonitor->statfilepath = statfilepath; if(pMonitor->rangeMs1 >= 0) { pMonitor->rangeMs1 = STREAM_STATS_RANGE_MS_LOW; } if(pMonitor->rangeMs2 >= 0) { pMonitor->rangeMs2 = STREAM_STATS_RANGE_MS_HIGH; } memset(&startWrap, 0, sizeof(startWrap)); startWrap.pMonitor = pMonitor; if((s = logutil_tid_lookup(pthread_self(), 0)) && s[0] != '\0') { snprintf(startWrap.tid_tag, sizeof(startWrap.tid_tag), "%s-mon", s); } pMonitor->runMonitor = 2; pMonitor->dumpIntervalMs = intervalMs; pthread_attr_init(&attrMonitor); pthread_attr_setdetachstate(&attrMonitor, PTHREAD_CREATE_DETACHED); if(pthread_create(&ptdMonitor, &attrMonitor, (void *) stream_monitor_proc, (void *) &startWrap) != 0) { LOG(X_ERROR("Unable to create stream output statistics monitor thread")); pMonitor->active = 0; pMonitor->runMonitor = 0; pthread_mutex_destroy(&pMonitor->mtx); return -1; } while(pMonitor->runMonitor != 1 && pMonitor->runMonitor != -1) { usleep(5000); } return rc; }
static int streamxmit_async_start(STREAM_RTP_MULTI_T *pRtp, STREAM_STATS_MONITOR_T *pMonitor, int lock) { int rc = 0; pthread_t ptdCap; pthread_attr_t attrCap; STREAMXMIT_WRAP_T wrap; const char *s; if(lock) { pthread_mutex_lock(&pRtp->mtx); } if(pRtp->asyncRtpRunning > 0) { if(lock) { pthread_mutex_unlock(&pRtp->mtx); } return 0; } pthread_mutex_init(&pRtp->asyncRtpCond.mtx, NULL); pthread_cond_init(&pRtp->asyncRtpCond.cond, NULL); wrap.pRtp = pRtp; wrap.pMonitor = pMonitor; wrap.tid_tag[0] = '\0'; if((s = logutil_tid_lookup(pthread_self(), 0)) && s[0] != '\0') { snprintf(wrap.tid_tag, sizeof(wrap.tid_tag), "%s-rtpxmit", s); } pRtp->asyncRtpRunning = 2; pthread_attr_init(&attrCap); pthread_attr_setdetachstate(&attrCap, PTHREAD_CREATE_DETACHED); if(pthread_create(&ptdCap, &attrCap, (void *) streamxmit_async_proc, (void *) &wrap) != 0) { LOG(X_ERROR("Unable to create RTP output thread")); pRtp->asyncRtpRunning = 0; pthread_cond_destroy(&pRtp->asyncRtpCond.cond); pthread_mutex_destroy(&pRtp->asyncRtpCond.mtx); if(lock) { pthread_mutex_unlock(&pRtp->mtx); } return -1; } if(lock) { pthread_mutex_unlock(&pRtp->mtx); } while(pRtp->asyncRtpRunning == 2) { usleep(5000); } return rc; }
int srvlisten_startmediasrv(SRV_LISTENER_CFG_T *pListenCfg, int async) { pthread_t ptdTsLive; pthread_attr_t attrTsLive; const char *s; int rc = 0; if(!pListenCfg || !pListenCfg->pConnPool || pListenCfg->max <= 0 || !pListenCfg->pCfg) { return -1; } if((pListenCfg->netflags & NETIO_FLAG_SSL_TLS) && !netio_ssl_enabled(1)) { LOG(X_ERROR("SSL not enabled")); return -1; } if(async) { if((s = logutil_tid_lookup(pthread_self(), 0)) && s[0] != '\0') { snprintf(pListenCfg->tid_tag, sizeof(pListenCfg->tid_tag), "%s-media", s); } PHTREAD_INIT_ATTR(&attrTsLive); if(pthread_create(&ptdTsLive, &attrTsLive, (void *) srvlisten_media_proc, (void *) pListenCfg) != 0) { LOG(X_ERROR("Unable to create live listener thread")); return -1; } } else { srvlisten_media_proc(pListenCfg); rc = 0; } return rc; }
int srvlisten_loop(SRV_LISTENER_CFG_T *pListenCfg, void *thread_func) { int salen; THREAD_FUNC_WRAPPER_ARG_T wrapArg; CLIENT_CONN_T *pConn; SOCKET_DESCR_T sdclient; int rc = -1; const char *s; //pthread_cond_t cond; pthread_mutex_t mtx; TIME_VAL tv0, tv1; char tmp[128]; #if defined(__APPLE__) int sockopt = 0; #endif // __APPLE__ if(!pListenCfg || !pListenCfg->pnetsockSrv || !pListenCfg->pConnPool || !thread_func || pListenCfg->pConnPool->numElements <= 0) { return -1; } //memset(&saSrv, 0, sizeof(saSrv)); memset(&sdclient.netsocket, 0, sizeof(sdclient.netsocket)); //salen = sizeof(saSrv); //if(getsockname(pListenCfg->pnetsockSrv->sock, (struct sockaddr *) &saSrv, (socklen_t *) &salen) != 0) { // LOG(X_ERROR("getsockopt failed on server socket")); //} pthread_mutex_init(&mtx, NULL); //pthread_cond_init(&cond, NULL); while(!g_proc_exit) { salen = sizeof(sdclient.sa); if((NETIOSOCK_FD(sdclient.netsocket) = accept(PNETIOSOCK_FD(pListenCfg->pnetsockSrv), (struct sockaddr *) &sdclient.sa, (socklen_t *) &salen)) == INVALID_SOCKET) { if(!g_proc_exit) { LOG(X_ERROR("%saccept failed on %s:%d"), ((pListenCfg->pnetsockSrv->flags & NETIO_FLAG_SSL_TLS) ? "SSL " : ""), //inet_ntoa(saSrv.sin_addr), ntohs(saSrv.sin_port)); FORMAT_NETADDR(pListenCfg->sa, tmp, sizeof(tmp)), ntohs(INET_PORT(pListenCfg->sa))); } break; } if(g_proc_exit) { break; } sdclient.netsocket.flags = pListenCfg->pnetsockSrv->flags; // // Find an available client thread to process the client request // if((pConn = (CLIENT_CONN_T *) pool_get(pListenCfg->pConnPool)) == NULL) { LOG(X_WARNING("No available connection for %s:%d (max:%d) on port %d"), FORMAT_NETADDR(sdclient.sa, tmp, sizeof(tmp)), ntohs(INET_PORT(sdclient.sa)), pListenCfg->pConnPool->numElements, ntohs(INET_PORT(pListenCfg->sa))); netio_closesocket(&sdclient.netsocket); continue; } #if defined(__APPLE__) sockopt = 1; if(setsockopt(NETIOSOCK_FD(sdclient.netsocket), SOL_SOCKET, SO_NOSIGPIPE, (char*) &sockopt, sizeof(sockopt)) != 0) { LOG(X_ERROR("Failed to set SO_NOSIGPIPE")); } #endif // __APPLE__ //pConn->psrvsaListen = &saSrv; //memcpy(&pConn->srvsaListen, &saSrv, sizeof(pConn->srvsaListen)); LOG(X_DEBUG("Accepted connection on port %d from %s:%d"), htons(INET_PORT(pListenCfg->sa)), FORMAT_NETADDR(sdclient.sa, tmp, sizeof(tmp)), htons(INET_PORT(sdclient.sa))); pthread_attr_init(&pConn->attr); pthread_attr_setdetachstate(&pConn->attr, PTHREAD_CREATE_DETACHED); memset(&pConn->sd.netsocket, 0, sizeof(pConn->sd.netsocket)); NETIO_SET(pConn->sd.netsocket, sdclient.netsocket); memcpy(&pConn->sd.sa, &sdclient.sa, INET_SIZE(sdclient)); pConn->pListenCfg = pListenCfg; NETIOSOCK_FD(sdclient.netsocket) = INVALID_SOCKET; wrapArg.thread_func = thread_func; wrapArg.pConnPool = pListenCfg->pConnPool; wrapArg.pConn = pConn; wrapArg.flags = 1; wrapArg.tid_tag[0] = '\0'; if((s = logutil_tid_lookup(pthread_self(), 0)) && s[0] != '\0') { snprintf(wrapArg.tid_tag, sizeof(wrapArg.tid_tag), "%s-%u", s, pConn->pool.id); } //wrapArg.pcond = &cond; //fprintf(stderr, "%d CALLING wrap: 0x%x pConn:0x%x\n", pthread_self(), &wrapArg, wrapArg.pConn); if((rc = pthread_create(&pConn->ptd, &pConn->attr, (void *) thread_func_wrapper, (void *) &wrapArg)) != 0) { LOG(X_ERROR("Unable to create connection handler thread on port %d from %s:%d (%d %s)"), htons(INET_PORT(pListenCfg->sa)), FORMAT_NETADDR(sdclient.sa, tmp, sizeof(tmp)), htons(INET_PORT(sdclient.sa)), rc, strerror(rc)); netio_closesocket(&pConn->sd.netsocket); pool_return(pListenCfg->pConnPool, &pConn->pool); wrapArg.flags = 0; //pthread_cond_broadcast(&cond); break; } pthread_attr_destroy(&pConn->attr); // // be careful not to reuse the same wrapArg instance // since the stack variable arguments could get // overwritten by the next loop iteration, before the thread proc is // invoked // //fprintf(stderr, "wait start\n"); tv0 = timer_GetTime(); //if(wrapArg.flags == 1) { // // It seems that calling pthread_cond_wait here to check if the thread creation is // complete is not completely reliable and portable, so we do the lame way // of sleeping and polling. // //pthread_cond_wait(&cond, &mtx); while(wrapArg.flags == 1) { usleep(100); if(((tv1 = timer_GetTime()) - tv0) / TIME_VAL_MS > 1000) { LOG(X_WARNING("Abandoning wait for connection thread start on port %d from %s:%d"), htons(INET_PORT(pListenCfg->sa)), FORMAT_NETADDR(pListenCfg->sa, tmp, sizeof(tmp)), ntohs(INET_PORT(pListenCfg->sa))); break; } } //fprintf(stderr, "THREAD STARTED AFTER %lld ns\n", (timer_GetTime() - tv0)); //} //fprintf(stderr, "wait done\n"); //while(wrapArg.flag == 1) { // usleep(10000); //} } //pthread_cond_destroy(&cond); pthread_mutex_destroy(&mtx); return rc; }
int rtspsrv_init(STREAM_RTSP_SESSIONS_T *pRtsp) { pthread_t ptdMonitor; struct sockaddr_storage sa; pthread_attr_t attrMonitor; RTSP_MONITOR_CTXT_T startCtxt; const char *s; if(!pRtsp || pRtsp->max <= 0) { return -1; } if(pRtsp->psessions) { avc_free((void *) &pRtsp->psessions); } destroy_rtspgetsessions(pRtsp); if(!(pRtsp->psessions = (RTSP_SESSION_T *) avc_calloc(pRtsp->max, sizeof(RTSP_SESSION_T)))) { return -1; } pRtsp->numRtspGetSessions = pRtsp->max * 2; if(!(pRtsp->pRtspGetSessionsBuf = (RTSP_HTTP_SESSION_T *) avc_calloc(pRtsp->numRtspGetSessions, sizeof(RTSP_HTTP_SESSION_T)))) { avc_free((void *) &pRtsp->psessions); pRtsp->numRtspGetSessions = 0; return -1; } pthread_mutex_init(&pRtsp->mtx, NULL); // // If all UDP / RTP sockets are bound to the same port then establish // the listener of this port prior to any RTSP interaction because some app // gateways may send some UDP polling data to the base port - and returning // an ICMP port unreachable would prevent such app gateways from allocating // UDP proxy ports // pRtsp->sockStaticLocalPort = INVALID_SOCKET; if(pRtsp->staticLocalPort > 0) { memset(&sa, 0, sizeof(sa)); sa.ss_family = AF_INET; ((struct sockaddr_in *) &sa)->sin_addr.s_addr = INADDR_ANY; INET_PORT(sa) = htons(pRtsp->staticLocalPort); if((pRtsp->sockStaticLocalPort = net_opensocket(SOCK_DGRAM, 0, 0, (struct sockaddr *) &sa)) == INVALID_SOCKET) { LOG(X_ERROR("Failed to open RTSP static local RTP port %d"), pRtsp->staticLocalPort); } else { if(net_setsocknonblock(pRtsp->sockStaticLocalPort, 1) < 0) { LOG(X_ERROR("Failed to listen on RTSP static local RTP port %d"), pRtsp->staticLocalPort); net_closesocket(&pRtsp->sockStaticLocalPort); } } //if(pRtsp->sockStaticLocalPort != INVALID_SOCKET) { // sain.sin_addr.s_addr = inet_addr("127.0.0.1"); // rc = sendto(pRtsp->sockStaticLocalPort, &sain, 1, 0, (struct sockaddr *) &sain, sizeof(sain)); // fprintf(stderr, "SENDTO:%d\n", rc); //} } // // Parse any CSV of quoted User-Agent matches which should try to force TCP interleaved mode // pRtsp->rtspForceTcpUAList.count = 0; if(pRtsp->rtspForceTcpUAList.str) { strutil_parse_csv(cbparse_entry_rtspua, pRtsp, pRtsp->rtspForceTcpUAList.str); } pRtsp->runMonitor = 2; memset(&startCtxt, 0, sizeof(startCtxt)); startCtxt.pRtsp = pRtsp; if((s = logutil_tid_lookup(pthread_self(), 0)) && s[0] != '\0') { snprintf(startCtxt.tid_tag, sizeof(startCtxt.tid_tag), "%s-rtspmon", s); } pthread_attr_init(&attrMonitor); pthread_attr_setdetachstate(&attrMonitor, PTHREAD_CREATE_DETACHED); if(pthread_create(&ptdMonitor, &attrMonitor, (void *) rtsp_monitor_proc, (void *) &startCtxt) != 0) { LOG(X_ERROR("Unable to create RTP monitor thread")); pRtsp->runMonitor = 0; if(pRtsp->psessions) { avc_free((void *) &pRtsp->psessions); } destroy_rtspgetsessions(pRtsp); pthread_mutex_destroy(&pRtsp->mtx); } while(pRtsp->runMonitor != 1 && pRtsp->runMonitor != -1) { usleep(5000); } return 0; }