void * CShairPlay::run(void* _this) { set_threadname("CShairPlay::run"); CShairPlay *T = (CShairPlay *) _this; dnssd_t *dnssd; raop_t *raop; raop_callbacks_t raop_cbs; memset(&raop_cbs, 0, sizeof(raop_cbs)); raop_cbs.cls = T; raop_cbs.audio_init = audio_init; raop_cbs.audio_flush = audio_flush; raop_cbs.audio_process = audio_process; raop_cbs.audio_destroy = audio_destroy; raop_cbs.audio_set_volume = audio_set_volume; raop_cbs.audio_set_metadata = audio_set_metadata; raop_cbs.audio_set_coverart = audio_set_coverart; raop = raop_init_from_keyfile(10, &raop_cbs, "/share/shairplay/airport.key", NULL); if (raop == NULL) { fprintf(stderr, "Could not initialize the RAOP service\n"); T->threadId = 0; pthread_exit(NULL); } raop_set_log_level(raop, RAOP_LOG_WARNING); short unsigned int port = g_settings.shairplay_port; raop_start(raop, &port, T->hwaddr, sizeof(T->hwaddr), g_settings.shairplay_password.empty() ? NULL : g_settings.shairplay_password.c_str()); dnssd = dnssd_init(NULL); if (dnssd) { dnssd_register_raop(dnssd, g_settings.shairplay_apname.c_str(), port, T->hwaddr, sizeof(T->hwaddr), 0); sem_wait(&T->sem); dnssd_unregister_raop(dnssd); dnssd_destroy(dnssd); } else { fprintf(stderr, "ERROR: Could not initialize dnssd library!\n"); } raop_stop(raop); raop_destroy(raop); T->threadId = 0; pthread_exit(NULL); }
void * nhttpd_main_thread(void *) { set_threadname(__func__); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0); pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); aprintf("Webserver %s tid %ld\n", WEBSERVERNAME, syscall(__NR_gettid)); yhttpd = new Cyhttpd(); //CLogging::getInstance()->setDebug(true); //CLogging::getInstance()->LogLevel = 9; if (!yhttpd) { aprintf("Error initializing WebServer\n"); return (void *) EXIT_FAILURE; } /* we pthread_cancel this thread from the main thread, but still want to clean up */ pthread_cleanup_push(thread_cleanup, yhttpd); #ifndef Y_CONFIG_FEATURE_THREADING yhttpd->flag_threading_off = true; #endif yhttpd->hooks_attach(); yhttpd->ReadConfig(); if (yhttpd->Configure()) { // Start Webserver: fork ist if not in debug mode aprintf("Webserver starting...\n"); dprintf("Start in Debug-Mode\n"); // non forked debugging loop yhttpd->run(); } pthread_cleanup_pop(0); delete yhttpd; yhttpd = NULL; aprintf("Main end\n"); return (void *) EXIT_SUCCESS; }
void create_thread_date_list() { memset(&_g_thread_datas,0,sizeof(_g_thread_datas)); pthread_key_create(&_g_thread_datas._key, NULL); set_threadname("main"); }
//----------------------------------------------------------------------------- // Main Webserver call //----------------------------------------------------------------------------- void Cyhttpd::run() { set_threadname(__func__); if (webserver) { if (flag_threading_off) webserver->is_threading = false; webserver->run(); stop_webserver(); } else aprintf("Error initializing WebServer\n"); }
void *insertEventsfromFile(void * data) { set_threadname(__func__); reader_ready=false; std::string indexname; std::string filename; std::string epgname; xmlNodePtr eventfile; int ev_count = 0; if (!data) { reader_ready = true; pthread_exit(NULL); } std::string epg_dir = (char *) data; indexname = epg_dir + "index.xml"; time_t now = time_monotonic_ms(); xmlDocPtr index_parser = parseXmlFile(indexname.c_str()); if (index_parser == NULL) { readEventsFromDir(epg_dir, ev_count); printf("[sectionsd] Reading Information finished after %ld milliseconds (%d events)\n", time_monotonic_ms()-now, ev_count); reader_ready = true; pthread_exit(NULL); } printdate_ms(stdout); printf("[sectionsd] Reading Information from file %s:\n", indexname.c_str()); eventfile = xmlDocGetRootElement(index_parser); eventfile = xmlChildrenNode(eventfile); while (eventfile) { const char * name = xmlGetAttribute(eventfile, "name"); if(name) filename=name; epgname = epg_dir + filename; readEventsFromFile(epgname, ev_count); eventfile = xmlNextNode(eventfile); } xmlFreeDoc(index_parser); printdate_ms(stdout); printf("[sectionsd] Reading Information finished after %ld milliseconds (%d events)\n", time_monotonic_ms()-now, ev_count); reader_ready = true; pthread_exit(NULL); }
void *cYTFeedParser::GetVideoUrlsThread(void *arg) { set_threadname("YT::GetVideoUrls"); int ret = 0; cYTFeedParser *caller = (cYTFeedParser *)arg; CURL *c = curl_easy_init(); unsigned int i; do { OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(caller->mutex); i = caller->worker_index++; } while (i < caller->videos.size() && ((ret |= caller->ParseVideoInfo(caller->videos[i], c)) || true)); curl_easy_cleanup(c); pthread_exit(&ret); }
void *cYTFeedParser::DownloadThumbnailsThread(void *arg) { set_threadname("YT::DownloadThumbnails"); bool ret = true; cYTFeedParser *caller = (cYTFeedParser *)arg; CURL *c = curl_easy_init(); unsigned int i; do { OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(caller->mutex); i = caller->worker_index++; } while (i < caller->videos.size() && ((ret &= caller->DownloadThumbnail(caller->videos[i], c)) || true)); curl_easy_cleanup(c); pthread_exit(&ret); }
static int run_map_thread(tribuf *tb) { set_threadname("render"); struct point_data *pd = new_point_data(opts.rational_julia?4:2); unsigned int beats = beat_get_count(); unsigned int tick0, fps_oldtime, frmcnt=0, last_beat_time = 0; tick0 = fps_oldtime = SDL_GetTicks(); unsigned int fpstimes[40]; for(int i=0; i<40; i++) fpstimes[i] = 0; uint16_t *map_src = tribuf_get_read_nolock(tb); while(running) { frmcnt++; if((tick0-SDL_GetTicks())*opts.maxsrc_rate + (maxfrms*1000) > 1000) { audio_data ad; audio_get_samples(&ad); maxsrc_update(maxsrc, ad.data, ad.len); audio_finish_samples(); maxfrms++; } uint16_t *map_dest = tribuf_get_write(tb); map_func(map_dest, map_src, im_w, im_h, pd); maxblend(map_dest, maxsrc_get(maxsrc), im_w, im_h); tribuf_finish_write(tb); map_src=map_dest; unsigned int now = SDL_GetTicks() - tick0; float fpsd = (now - fpstimes[frmcnt%40])/1000.0f; fpstimes[frmcnt%40] = now; map_fps = 40.0f / fpsd; unsigned int newbeat = beat_get_count(); if(newbeat != beats && now - last_beat_time > 1000) { last_beat_time = now; update_points(pd, now, 1); } else update_points(pd, now, 0); beats = newbeat; if(map_fps > 750) SDL_Delay(1); // hard limit ourselves because 1500FPS is just pointless use of CPU (except of course to say that we can do it) // also if we run at more that 1000FPS the point motion code might blow up without the microsecond accurate timers... // high threshhold because we want it high enough that we don't notice if we jitter back // and fourth across it } return 0; }
void *CShairPlay::showPicThread (void *_this) { set_threadname("CShairPlay::showPic"); CShairPlay *T = (CShairPlay *) _this; unlink(COVERART_M2V); T->lock(&T->videoMutex); if (*T->active) #if HAVE_COOL_HARDWARE // FIXME. The second argument on non-CST hardware is just to avoid caching the m2v. // No idea whether this would be advisable on CST hardware. --martii videoDecoder->ShowPicture(COVERART); #else videoDecoder->ShowPicture(COVERART, COVERART_M2V); #endif T->unlock(&T->videoMutex); pthread_exit(NULL); }
void *cYTCache::downloadThread(void *arg) { fprintf(stderr, "%s starting\n", __func__); set_threadname("ytdownload"); cYTCache *caller = (cYTCache *)arg; //CVFD::getInstance()->ShowIcon(FP_ICON_DOWNLOAD, true); while (caller->thread) { MI_MOVIE_INFO mi; { OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(caller->mutex); if (caller->pending.empty()) { caller->cancelled = false; caller->thread = 0; continue; } mi = caller->pending.front(); } bool res = caller->download(&mi); caller->cancelled = false; { OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(caller->mutex); if (res) caller->completed.insert(caller->completed.begin(), mi); else caller->failed.insert(caller->failed.begin(), mi); if (caller->pending.empty()) caller->thread = 0; else caller->pending.erase(caller->pending.begin()); } } //CVFD::getInstance()->ShowIcon(FP_ICON_DOWNLOAD, false); fprintf(stderr, "%s exiting\n", __func__); pthread_exit(NULL); }
void *cHddStat::Run(void *arg) { set_threadname("hddstat"); class cHddStat *caller = (class cHddStat *)arg; timespec ts; clock_gettime(CLOCK_REALTIME, &ts); long long oldperc = -2; caller->once = g_settings.hdd_statfs_mode != SNeutrinoSettings::HDD_STATFS_OFF; while (caller->running) { std::string _dir; pthread_mutex_lock(&caller->mutex); _dir = caller->dir; pthread_mutex_unlock(&caller->mutex); long long perc = -1; if (caller->once || (g_settings.hdd_statfs_mode == SNeutrinoSettings::HDD_STATFS_ALWAYS) || (g_settings.hdd_statfs_mode == SNeutrinoSettings::HDD_STATFS_RECORDING && (CRecordManager::getInstance()->RecordingStatus() || cYTCache::getInstance()->isActive()))) { caller->once = false; struct statfs st; if (statfs(_dir.c_str(), &st) || !st.f_blocks) perc = -1; else perc = 100 * (long long)(st.f_blocks - st.f_bfree) / (long long) st.f_blocks; } else perc = oldperc; if (oldperc != perc) { oldperc = perc; caller->percent = (int) perc; CVFD::getInstance()->setHddUsage(perc); } ts.tv_sec += caller->period; sem_timedwait(&caller->sem, &ts); } pthread_exit(NULL); }
void * TcpReceiver( void * Ptr ) { set_threadname(__func__); char TcpString[STRING_SIZE], PacketString[STRING_SIZE]; unsigned SPktBuf, u; (void)Ptr; while(true) { ReadLine( TcpString ); if( !strncmp(TcpString, "RESEND", 6)) { if ( 2 != sscanf(TcpString, "RESEND %u %s", &SPktBuf, PacketString) ) { fprintf(stderr, "ERROR: TcpReceiver - sscanf RESEND\n"); continue; } for( u=0; u<SPKT_BUF_PACKET_NUM; u++) { if (PacketString[u] == 'y') { SPkt.ReSend[SPktBuf][u] = 1; } else { SPkt.ReSend[SPktBuf][u] = 0; } } SPkt.ReSendStatus[SPktBuf] = 1; } else if ( !strncmp(TcpString, "STOP", 4 )) { StreamStop=1; break; } else { fprintf(stderr, "ERROR: TcpReader - illegal command\n"); fflush(stderr); } } sleep(3); printf("EXIT\n" ); fflush(stdout); exit(0); // jetzt sollte main() schon bei exit(0) sein }
void * CShairPlay::audioThread(void *_this) { set_threadname("CShairPlay::audioThread"); CShairPlay *T = (CShairPlay *) _this; #if __BYTE_ORDER == __LITTLE_ENDIAN audioDecoder->PrepareClipPlay(T->channels, T->samplerate, T->bits, 1); #else audioDecoder->PrepareClipPlay(T->channels, T->samplerate, T->bits, 0); #endif int running = true; while (running) { sem_wait(&T->audioSem); T->lock(&T->audioMutex); if (T->audioQueue.empty()) { T->unlock(&T->audioMutex); break; } audioQueueStruct *q = T->audioQueue.front(); T->audioQueue.pop_front(); T->unlock(&T->audioMutex); for (int i=0; i<q->len/2; i++) q->buf[i] = q->buf[i] * T->volume; if (*T->active && audioDecoder->WriteClip((unsigned char *)q->buf, q->len) != q->len) // probably shutting down running = false; free(q); } audioDecoder->StopClip(); T->audioThreadId = 0; pthread_exit(NULL); }
static void* dvbsub_thread(void* /*arg*/) { struct timespec restartWait; struct timeval now; set_threadname("dvbsub:main"); sub_debug.print(Debug::VERBOSE, "%s started\n", __FUNCTION__); if (!dvbSubtitleConverter) dvbSubtitleConverter = new cDvbSubtitleConverter; int timeout = 1000000; #if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE CFrameBuffer *fb = CFrameBuffer::getInstance(); int xres = fb->getScreenWidth(true); int yres = fb->getScreenHeight(true); int clr_x0 = xres, clr_y0 = yres, clr_x1 = 0, clr_y1 = 0; uint32_t colortable[256]; memset(colortable, 0, sizeof(colortable)); uint32_t last_color = 0; #endif while(dvbsub_running) { #if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE if (ass_track) { usleep(100000); // FIXME ... should poll instead OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(ass_mutex); if (!ass_track) continue; if (ass_size != sub_font_size) { ass_size = sub_font_size; ass_set_font_scale(ass_renderer, ((double) ass_size)/ASS_CUSTOM_FONT_SIZE); } int detect_change = 0; int64_t pts; getPlayerPts(&pts); ASS_Image *image = ass_render_frame(ass_renderer, ass_track, pts/90, &detect_change); if (detect_change) { if (clr_x1 && clr_y1) { fb->paintBox(clr_x0, clr_y0, clr_x1 + 1, clr_y1 + 1, 0); clr_x0 = xres; clr_y0 = yres; clr_x1 = clr_y1 = 0; } while (image) { if (last_color != image->color) { last_color = image->color; uint32_t c = last_color >> 8, a = 255 - (last_color & 0xff); for (int i = 0; i < 256; i++) { uint32_t k = (a * i) >> 8; colortable[i] = k ? (c | (k << 24)) : 0; } } if (image->w && image->h && image->dst_x > -1 && image->dst_x + image->w < xres && image->dst_y > -1 && image->dst_y + image->h < yres) { if (image->dst_x < clr_x0) clr_x0 = image->dst_x; if (image->dst_y < clr_y0) clr_y0 = image->dst_y; if (image->dst_x + image->w > clr_x1) clr_x1 = image->dst_x + image->w; if (image->dst_y + image->h > clr_y1) clr_y1 = image->dst_y + image->h; uint32_t *lfb = fb->getFrameBufferPointer() + image->dst_x + xres * image->dst_y; unsigned char *bm = image->bitmap; int bm_add = image->stride - image->w; int lfb_add = xres - image->w; for (int y = 0; y < image->h; y++) { for (int x = 0; x < image->w; x++) { if (*bm) *lfb = colortable[*bm]; lfb++, bm++; } lfb += lfb_add; bm += bm_add; } } image = image->next; } fb->getInstance()->blit(); } continue; } else { if (clr_x1 && clr_y1) {
static void* reader_thread(void * /*arg*/) { int fds[2]; pipe(fds); fcntl(fds[0], F_SETFD, FD_CLOEXEC); fcntl(fds[0], F_SETFL, O_NONBLOCK); fcntl(fds[1], F_SETFD, FD_CLOEXEC); fcntl(fds[1], F_SETFL, O_NONBLOCK); flagFd = fds[1]; uint8_t tmp[16]; /* actually 6 should be enough */ int count; int len; uint16_t packlen; uint8_t* buf; bool bad_startcode = false; set_threadname("dvbsub:reader"); dmx = new cDemux(0); #if HAVE_TRIPLEDRAGON dmx->Open(DMX_PES_CHANNEL, NULL, 16*1024); #else dmx->Open(DMX_PES_CHANNEL, NULL, 64*1024); #endif while (reader_running) { if(dvbsub_stopped /*dvbsub_paused*/) { sub_debug.print(Debug::VERBOSE, "%s stopped\n", __FUNCTION__); dmx->Stop(); pthread_mutex_lock(&packetMutex); pthread_cond_broadcast(&packetCond); pthread_mutex_unlock(&packetMutex); pthread_mutex_lock(&readerMutex ); int ret = pthread_cond_wait(&readerCond, &readerMutex); pthread_mutex_unlock(&readerMutex); if (ret) { sub_debug.print(Debug::VERBOSE, "pthread_cond_timedwait fails with %d\n", ret); } if(!reader_running) break; dvbsub_stopped = 0; sub_debug.print(Debug::VERBOSE, "%s (re)started with pid 0x%x\n", __FUNCTION__, dvbsub_pid); } if(pid_change_req) { pid_change_req = 0; clear_queue(); dmx->Stop(); dmx->pesFilter(dvbsub_pid); dmx->Start(); sub_debug.print(Debug::VERBOSE, "%s changed to pid 0x%x\n", __FUNCTION__, dvbsub_pid); } struct pollfd pfds[2]; pfds[0].fd = fds[1]; pfds[0].events = POLLIN; char _tmp[64]; #if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE if (isEplayer) { poll(pfds, 1, -1); while (0 > read(pfds[0].fd, _tmp, sizeof(tmp))); continue; } #endif pfds[1].fd = dmx->getFD(); pfds[1].events = POLLIN; switch (poll(pfds, 2, -1)) { case 0: case -1: if (pfds[0].revents & POLLIN) while (0 > read(pfds[0].fd, _tmp, sizeof(tmp))); continue; default: if (pfds[0].revents & POLLIN) while (0 > read(pfds[0].fd, _tmp, sizeof(tmp))); if (!(pfds[1].revents & POLLIN)) continue; } len = dmx->Read(tmp, 6, 0); if(len <= 0) continue; if(!memcmp(tmp, "\x00\x00\x01\xbe", 4)) { // padding stream packlen = getbits(tmp, 4*8, 16) + 6; count = 6; buf = (uint8_t*) malloc(packlen); // actually, we're doing slightly too much here ... memmove(buf, tmp, 6); /* read rest of the packet */ while((count < packlen) && !dvbsub_stopped) { len = dmx->Read(buf+count, packlen-count, 1000); if (len < 0) { break; } else { count += len; } } free(buf); buf = NULL; continue; } if(memcmp(tmp, "\x00\x00\x01\xbd", 4)) { if (!bad_startcode) { sub_debug.print(Debug::VERBOSE, "[subtitles] bad start code: %02x%02x%02x%02x\n", tmp[0], tmp[1], tmp[2], tmp[3]); bad_startcode = true; } continue; } bad_startcode = false; count = 6; packlen = getbits(tmp, 4*8, 16) + 6; buf = (uint8_t*) malloc(packlen); memmove(buf, tmp, 6); /* read rest of the packet */ while((count < packlen) && !dvbsub_stopped) { len = dmx->Read(buf+count, packlen-count, 1000); if (len < 0) { break; } else { count += len; } } #if 0 for(int i = 6; i < packlen - 4; i++) { if(!memcmp(&buf[i], "\x00\x00\x01\xbd", 4)) { int plen = getbits(&buf[i], 4*8, 16) + 6; sub_debug.print(Debug::VERBOSE, "[subtitles] ******************* PES header at %d ?! *******************\n", i); sub_debug.print(Debug::VERBOSE, "[subtitles] start code: %02x%02x%02x%02x len %d\n", buf[i+0], buf[i+1], buf[i+2], buf[i+3], plen); free(buf); continue; } } #endif if(!dvbsub_stopped /*!dvbsub_paused*/) { sub_debug.print(Debug::VERBOSE, "[subtitles] *** new packet, len %d buf 0x%x pts-stc diff %lld ***\n", count, buf, get_pts_stc_delta(get_pts(buf))); /* Packet now in memory */ pthread_mutex_lock(&packetMutex); packet_queue.push(buf); /* TODO: allocation exception */ // wake up dvb thread pthread_cond_broadcast(&packetCond); pthread_mutex_unlock(&packetMutex); } else { free(buf); buf=NULL; } } dmx->Stop(); delete dmx; dmx = NULL; close(fds[0]); close(fds[1]); flagFd = -1; sub_debug.print(Debug::VERBOSE, "%s shutdown\n", __FUNCTION__); pthread_exit(NULL); }
static void *ass_reader_thread(void *) { set_threadname("ass_reader_thread"); while (!sem_wait(&ass_sem)) { if (!ass_reader_running) break; ass_data *a = (ass_data *) ass_queue.pop(); if (!a) { if (!ass_reader_running) break; continue; } OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(ass_mutex); std::map<int,ASS_Track*>::iterator it = ass_map.find(a->pid); ASS_Track *track; if (it == ass_map.end()) { CFrameBuffer *fb = CFrameBuffer::getInstance(); int xres = fb->getScreenWidth(true); int yres = fb->getScreenHeight(true); if (!ass_library) { ass_library = ass_library_init(); ass_set_extract_fonts(ass_library, 1); ass_set_style_overrides(ass_library, NULL); ass_renderer = ass_renderer_init(ass_library); ass_set_frame_size(ass_renderer, xres, yres); ass_set_margins(ass_renderer, 3 * yres / 100, 3 * yres / 100, 3 * xres / 100, 3 * xres / 100); ass_set_use_margins(ass_renderer, 1); ass_set_hinting(ass_renderer, ASS_HINTING_LIGHT); ass_set_aspect_ratio(ass_renderer, 1.0, 1.0); ass_font = *sub_font_file; ass_set_fonts(ass_renderer, ass_font.c_str(), "Arial", 0, NULL, 1); } track = ass_new_track(ass_library); track->PlayResX = xres; track->PlayResY = yres; ass_size = sub_font_size; ass_set_font_scale(ass_renderer, ((double) ass_size)/ASS_CUSTOM_FONT_SIZE); if (a->c->subtitle_header) { std::string ass_hdr = ass_subtitle_header_default(); if (ass_hdr.compare((char*) a->c->subtitle_header)) { ass_process_codec_private(track, (char *) a->c->subtitle_header, a->c->subtitle_header_size); } else { // This is the FFMPEG default ASS header. Use something more suitable instead: ass_hdr = ass_subtitle_header_custom(); ass_process_codec_private(track, (char *) ass_hdr.c_str(), ass_hdr.length()); } } ass_map[a->pid] = track; if (a->pid == dvbsub_pid) ass_track = track; //fprintf(stderr, "### got subtitle track %d, subtitle header: \n---\n%s\n---\n", pid, c->subtitle_header); } else track = it->second; for (unsigned int i = 0; i < a->sub.num_rects; i++) if (a->sub.rects[i]->ass) ass_process_data(track, a->sub.rects[i]->ass, strlen(a->sub.rects[i]->ass)); avsubtitle_free(&a->sub); delete a; } ass_reader_running = false; pthread_exit(NULL); }
void CAdZapMenu::Run() { set_threadname("CAdZapMenu::Run"); while (true) { CChannelList *channelList = NULL; t_channel_id curChannelId = -1; if (monitor) { clock_gettime(CLOCK_REALTIME, &ts); ts.tv_sec += 1; sem_timedwait(&sem, &ts); if (monitor && (monitorLifeTime.tv_sec > ts.tv_sec)) { channelList = CNeutrinoApp::getInstance()->channelList; curChannelId = channelList ? channelList->getActiveChannel_ChannelID() : -1; if (!armed && (channelId != curChannelId)) { armed = true; clock_gettime(CLOCK_REALTIME, &zapBackTime); zapBackTime.tv_sec += g_settings.adzap_zapBackPeriod - ZAPBACK_ALERT_PERIOD; alerted = false; } else if (channelId == curChannelId) { armed = false; alerted = false; } } else { monitor = false; armed = false; alerted = false; } } else if (armed) { if (g_settings.adzap_writeData) { clock_gettime(CLOCK_REALTIME, &ts); ts.tv_sec += 1; sem_timedwait(&sem, &ts); } else sem_timedwait(&sem, &zapBackTime); } else sem_wait(&sem); if (armed) { clock_gettime(CLOCK_REALTIME, &ts); if (ts.tv_sec >= zapBackTime.tv_sec) { if (!channelList) { channelList = CNeutrinoApp::getInstance()->channelList; curChannelId = channelList ? channelList->getActiveChannel_ChannelID() : -1; } if (!alerted) { if (channelId != curChannelId) { char name[1024]; snprintf(name, sizeof(name)-1, g_Locale->getText(LOCALE_ADZAP_ANNOUNCE), ZAPBACK_ALERT_PERIOD, channelName.c_str()); ShowHint(LOCALE_ADZAP, name); } alerted = true; zapBackTime.tv_sec += ZAPBACK_ALERT_PERIOD; } else { alerted = false; if ((channelId != curChannelId) && channelList) channelList->zapTo_ChannelID(channelId); armed = false; } } } if (g_settings.adzap_writeData && (monitor || armed)) WriteData(); else RemoveData(); } }
bool CWebserver::run(void) { set_threadname(__func__); if (!listenSocket.listen(port, HTTPD_MAX_CONNECTIONS)) { if (port != 80) { fprintf(stderr, "[yhttpd] Socket cannot bind and listen on port %d Abort.\n", port); return false; } fprintf(stderr, "[yhttpd] cannot bind and listen on port 80, retrying on port 8080.\n"); port = 8080; if (!listenSocket.listen(port, HTTPD_MAX_CONNECTIONS)) { fprintf(stderr, "[yhttpd] Socket cannot bind and listen on port %d Abort.\n", port); return false; } } #ifdef Y_CONFIG_FEATURE_KEEP_ALIVE // initialize values for select int listener = listenSocket.get_socket();// Open Listener struct timeval tv; // timeout struct FD_SET(listener, &master); // add the listener to the master set fdmax = listener; // init max fd fcntl(listener, F_SETFD , O_NONBLOCK); // listener master socket non-blocking int timeout_counter = 0; // Counter for Connection Timeout checking int test_counter = 0; // Counter for Testing long running Connections // main Webserver Loop while(!terminate) { // select : init vars read_fds = master; // copy it tv.tv_usec = 10000; // microsec: Timeout for select ! for re-use / keep-alive socket tv.tv_sec = 0; // seconds int fd = -1; // select : wait for socket activity if(open_connections <= 0) // No open Connection. Wait in select. fd = select(fdmax+1,&read_fds, NULL, NULL, NULL);// wait for socket activity else fd = select(fdmax+1,&read_fds, NULL, NULL, &tv);// wait for socket activity or timeout // too much to do : sleep if(open_connections >= HTTPD_MAX_CONNECTIONS-1) sleep(1); // Socket Error? if(fd == -1 && errno != EINTR) { perror("select"); return false; } // Socket Timeout? if(fd == 0) { // Testoutput for long living threads if(++test_counter >= MAX_TIMEOUTS_TO_TEST) { for(int j=0;j < HTTPD_MAX_CONNECTIONS;j++) if(SocketList[j] != NULL) // here is a socket log_level_printf(2,"FD-TEST sock:%d handle:%d open:%d\n",SocketList[j]->get_socket(), SocketList[j]->handling,SocketList[j]->isOpened); test_counter=0; } // some connection closing previous missed? if(++timeout_counter >= MAX_TIMEOUTS_TO_CLOSE) { CloseConnectionSocketsByTimeout(); timeout_counter=0; } continue; // main loop again } //---------------------------------------------------------------------------------------- // Check all observed descriptors & check new or re-use Connections //---------------------------------------------------------------------------------------- for(int i = listener; i <= fdmax; i++) { int slot = -1; if(FD_ISSET(i, &read_fds)) // Socket observed? { // we got one!! if (i == listener) // handle new connections slot = AcceptNewConnectionSocket(); else // Connection on an existing open Socket = reuse (keep-alive) { slot = SL_GetExistingSocket(i); if(slot>=0) log_level_printf(2,"FD: reuse con fd:%d\n",SocketList[slot]->get_socket()); } // prepare Connection handling if(slot>=0) if(SocketList[slot] != NULL && !SocketList[slot]->handling && SocketList[slot]->isValid) { log_level_printf(2,"FD: START CON HANDLING con fd:%d\n",SocketList[slot]->get_socket()); FD_CLR(SocketList[slot]->get_socket(), &master); // remove from master set SocketList[slot]->handling = true; // prepares for thread-handling if(!handle_connection(SocketList[slot]))// handle this activity { // Can not handle more threads char httpstr[]=HTTP_PROTOCOL " 503 Service Unavailable\r\n\r\n"; SocketList[slot]->Send(httpstr, strlen(httpstr)); SL_CloseSocketBySlot(slot); } } } }// for CloseConnectionSocketsByTimeout(); // Check connections to close }//while #else while (!terminate) { CySocket *newConnectionSock; if (!(newConnectionSock = listenSocket.accept())) //Now: Blocking wait { pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_testcancel(); dperror("Socket accept error. Continue.\n"); continue; } log_level_printf(3, "Socket connect from %s\n", (listenSocket.get_client_ip()).c_str()); #ifdef Y_CONFIG_USE_OPEN_SSL if(Cyhttpd::ConfigList["SSL"]=="true") newConnectionSock->initAsSSL(); // make it a SSL-socket #endif handle_connection(newConnectionSock); } #endif return true; }