Project

General

Profile

Feature #649 » close-all-fd.patch

Richard Kunze, 2012-05-10 02:37

View differences:

src/dvb/dvb.h
183 183
  gtimer_t tda_mux_scanner_timer;
184 184

  
185 185
  pthread_mutex_t tda_delivery_mutex;
186
  pthread_t tda_delivery_thread;
186 187
  struct service_list tda_transports; /* Currently bound transports */
187 188

  
188 189
  gtimer_t tda_fe_monitor_timer;
......
204 205

  
205 206
  int tda_unc_is_delta;  /* 1 if we believe FE_READ_UNCORRECTED_BLOCKS
206 207
			  * return dela values */
208
  int tda_opened;
207 209

  
208 210
} th_dvb_adapter_t;
209 211

  
......
243 245

  
244 246
void dvb_adapter_notify(th_dvb_adapter_t *tda);
245 247

  
248
void dvb_adapter_restart(th_dvb_adapter_t *tda);
249

  
246 250
htsmsg_t *dvb_adapter_build_msg(th_dvb_adapter_t *tda);
247 251

  
248 252
htsmsg_t *dvb_fe_opts(th_dvb_adapter_t *tda, const char *which);
src/dvb/dvb_adapter.c
63 63

  
64 64
  tda->tda_allpids_dmx_fd = -1;
65 65
  tda->tda_dump_fd = -1;
66
  tda->tda_opened = 0;
67
  tda->tda_fe_fd = -1;
66 68

  
67 69
  return tda;
68 70
}
......
177 179
void
178 180
dvb_adapter_set_dump_muxes(th_dvb_adapter_t *tda, int on)
179 181
{
180
  if(tda->tda_dump_muxes == on)
181
    return;
182
  if(tda->tda_dump_muxes == on)    return;
182 183

  
183 184
  lock_assert(&global_lock);
184 185

  
......
257 258
  int fe, i, r;
258 259
  th_dvb_adapter_t *tda;
259 260
  char buf[400];
260
  pthread_t ptid;
261 261

  
262 262
  snprintf(path, sizeof(path), "/dev/dvb/adapter%d", adapter_num);
263 263
  snprintf(fname, sizeof(fname), "%s/frontend0", path);
......
281 281

  
282 282

  
283 283
  tda->tda_fe_fd = fe;
284
  tda->tda_opened = 1;
284 285

  
285 286
  tda->tda_fe_info = malloc(sizeof(struct dvb_frontend_info));
286 287

  
......
321 322

  
322 323
  TAILQ_INSERT_TAIL(&dvb_adapters, tda, tda_global_link);
323 324

  
324
  pthread_create(&ptid, NULL, dvb_adapter_input_dvr, tda);
325

  
325
  pthread_create(&tda->tda_delivery_thread, NULL, dvb_adapter_input_dvr, tda);
326
  
326 327
  dvb_table_init(tda);
327 328

  
328 329
  if(tda->tda_sat)
......
391 392
    dvb_mux_load(tda);
392 393
}
393 394

  
395
static void dvb_close_idle_adapter(th_dvb_adapter_t *tda) 
396
{
397
  tvhlog(LOG_DEBUG, "dvb", "\"%s\" is idle, closing all device file descriptors", tda->tda_rootpath);
398
  if (tda->tda_delivery_thread != 0) {
399
     pthread_cancel(tda->tda_delivery_thread);
400
     pthread_join(tda->tda_delivery_thread, NULL);
401
     tda->tda_delivery_thread = 0;
402
  }
403
  dvb_fe_stop(tda->tda_mux_current);
404
  if (tda->tda_fe_fd != -1) {
405
    close(tda->tda_fe_fd);
406
    tda->tda_fe_fd = -1;
407
  }
408
  tda->tda_opened = 0;
409
}
410

  
411
/**
412
 * Restart an adapter that has been closed by dvb_close_idle_adapter()
413
 */
414
void 
415
dvb_adapter_restart(th_dvb_adapter_t *tda) 
416
{    
417
    char fname[256];
418
    snprintf(fname, sizeof(fname), "%s/frontend0", tda->tda_rootpath);
419
    tda->tda_fe_fd = tvh_open(fname, O_RDWR | O_NONBLOCK, 0);
420
    if (tda->tda_fe_fd != -1) {
421
      tda->tda_opened = 1;
422
      pthread_create(&tda->tda_delivery_thread, NULL, dvb_adapter_input_dvr, tda);      
423
    } else {
424
      tda->tda_opened = 0;
425
    }
426
}
394 427

  
395 428
/**
396 429
 * If nobody is subscribing, cycle thru all muxes to get some stats
......
420 453
    return;
421 454
  }
422 455

  
456
  if (tda->tda_opened == 0)
457
    return; // Tuner is closed
458

  
423 459
  if(!tda->tda_idlescan && TAILQ_FIRST(&tda->tda_scan_queues[0]) == NULL) {
424 460
    /* Idlescan is disabled and no muxes are bad */
425 461

  
426
    if(!tda->tda_qmon)
427
      return; // Quality monitoring is disabled
428

  
429
    /* If the currently tuned mux is ok, we can stick to it */
462
    if(tda->tda_qmon) // Check if quality monitoring is enabled
463
    {
464
      /* If the currently tuned mux is ok, we can stick to it */
430 465
    
431
    tdmi = tda->tda_mux_current;
432
    if(tdmi != NULL && tdmi->tdmi_quality > 90)
466
      tdmi = tda->tda_mux_current;
467
      if(tdmi != NULL && tdmi->tdmi_quality > 90)
468
      {
469
        dvb_close_idle_adapter(tda);
470
        return;
471
      }
472
    }
473
    else
474
    {
475
      dvb_close_idle_adapter(tda);
433 476
      return;
477
    }
434 478
  }
435 479

  
436 480
  /* Alternate between the other two (bad and OK) */
......
510 554

  
511 555

  
512 556

  
557
static void
558
dvb_adapter_close_fd(void *aux) 
559
{
560
  int *fd = aux;
561
  if (*fd != -1) {
562
    close(*fd);
563
    *fd = -1;
564
  }
565
}
513 566

  
514 567
/**
515 568
 *
......
527 580
    tvhlog(LOG_ALERT, "dvb", "%s: unable to open dvr", tda->tda_dvr_path);
528 581
    return NULL;
529 582
  }
530

  
531

  
583
  pthread_cleanup_push(dvb_adapter_close_fd, &fd);
532 584
  while(1) {
533 585
    r = read(fd, tsb, sizeof(tsb));
534 586

  
......
553 605

  
554 606
    pthread_mutex_unlock(&tda->tda_delivery_mutex);
555 607
  }
608
  pthread_cleanup_pop(1);
556 609
}
557 610

  
558 611

  
src/dvb/dvb_fe.c
422 422
  
423 423
  char buf[256];
424 424
  int r;
425
 
426 425

  
427 426
  lock_assert(&global_lock);
428 427

  
429
  if(tda->tda_mux_current == tdmi)
430
    return 0;
428
  if(!tda->tda_opened)
429
  {
430
    dvb_adapter_restart(tda);
431
  }
432

  
433
  if(tda->tda_mux_current != NULL)
434
    dvb_fe_stop(tda->tda_mux_current);
431 435
  
432 436
  if(tdmi->tdmi_scan_queue != NULL) {
433 437
    TAILQ_REMOVE(tdmi->tdmi_scan_queue, tdmi, tdmi_scan_link);
434 438
    tdmi->tdmi_scan_queue = NULL;
435 439
  }
436

  
437
  if(tda->tda_mux_current != NULL)
438
    dvb_fe_stop(tda->tda_mux_current);
439

  
440 440
    
441 441
  if(tda->tda_type == FE_QPSK) {
442 442
	
src/wrappers.c
1 1
#include <fcntl.h>
2
#include <unistd.h>
2 3
#include <sys/types.h>          /* See NOTES */
3 4
#include <sys/socket.h>
4 5
#include "tvheadend.h"
......
16 17
  return fd;
17 18
}
18 19

  
19

  
20 20
int
21 21
tvh_socket(int domain, int type, int protocol)
22 22
{
(2-2/2)