Ticket #3381: fifowriter.rev2.patch
File fifowriter.rev2.patch, 12.2 KB (added by , 17 years ago) |
---|
-
hdtvrecorder.h
85 85 // Data for managing the device ringbuffer 86 86 struct { 87 87 pthread_t thread; 88 mutable pthread_mutex_tlock;89 mutable pthread_mutex_tlock_stats;88 mutable QMutex lock; 89 mutable QMutex lock_stats; 90 90 91 91 bool run; 92 92 bool eof; -
hdtvrecorder.cpp
128 128 129 129 ringbuf.run = false; 130 130 ringbuf.buffer = 0; 131 pthread_mutex_init(&ringbuf.lock, NULL);132 pthread_mutex_init(&ringbuf.lock_stats, NULL);133 131 loop = random() % (report_loops / 2); 134 132 } 135 133 … … 156 154 HDTVRecorder::~HDTVRecorder() 157 155 { 158 156 TeardownAll(); 159 pthread_mutex_destroy(&ringbuf.lock);160 pthread_mutex_destroy(&ringbuf.lock_stats);161 157 } 162 158 163 159 void HDTVRecorder::SetOptionsFromProfile(RecordingProfile *profile, … … 296 292 size_t read_size; 297 293 bool run, request_pause, paused; 298 294 299 pthread_mutex_lock(&ringbuf.lock);295 ringbuf.lock.lock(); 300 296 ringbuf.run = true; 301 pthread_mutex_unlock(&ringbuf.lock);297 ringbuf.lock.unlock(); 302 298 303 299 for (;;) 304 300 { 305 pthread_mutex_lock(&ringbuf.lock);301 ringbuf.lock.lock(); 306 302 run = ringbuf.run; 307 303 unused = ringbuf.size - ringbuf.used; 308 304 request_pause = ringbuf.request_pause; 309 305 paused = ringbuf.paused; 310 pthread_mutex_unlock(&ringbuf.lock);306 ringbuf.lock.unlock(); 311 307 312 308 if (!run) 313 309 break; 314 310 315 311 if (request_pause) 316 312 { 317 pthread_mutex_lock(&ringbuf.lock);313 ringbuf.lock.lock(); 318 314 ringbuf.paused = true; 319 pthread_mutex_unlock(&ringbuf.lock);315 ringbuf.lock.unlock(); 320 316 321 317 pauseWait.wakeAll(); 322 318 if (tvrec) … … 327 323 } 328 324 else if (paused) 329 325 { 330 pthread_mutex_lock(&ringbuf.lock);326 QMutexLocker locker(&ringbuf.lock); 331 327 ringbuf.writePtr = ringbuf.readPtr = ringbuf.buffer; 332 328 ringbuf.used = 0; 333 329 ringbuf.paused = false; 334 pthread_mutex_unlock(&ringbuf.lock);335 330 } 336 331 337 332 contiguous = ringbuf.endPtr - ringbuf.writePtr; … … 339 334 while (unused < TSPacket::SIZE && contiguous > TSPacket::SIZE) 340 335 { 341 336 usleep(500); 337 338 QMutexLocker locker(&ringbuf.lock); 342 339 343 pthread_mutex_lock(&ringbuf.lock);344 340 unused = ringbuf.size - ringbuf.used; 345 341 request_pause = ringbuf.request_pause; 346 pthread_mutex_unlock(&ringbuf.lock);347 342 348 343 if (request_pause) 349 344 break; … … 367 362 perror("read"); 368 363 if (++errcnt > 5) 369 364 { 370 pthread_mutex_lock(&ringbuf.lock);365 QMutexLocker locker(&ringbuf.lock); 371 366 ringbuf.error = true; 372 pthread_mutex_unlock(&ringbuf.lock);373 374 367 break; 375 368 } 376 369 … … 383 376 { 384 377 VERBOSE(VB_IMPORTANT, QString("HD8 %1 end of file found.") 385 378 .arg(videodevice)); 386 387 pthread_mutex_lock(&ringbuf.lock); 379 QMutexLocker locker(&ringbuf.lock); 388 380 ringbuf.eof = true; 389 pthread_mutex_unlock(&ringbuf.lock);390 391 381 break; 392 382 } 393 383 usleep(500); … … 396 386 397 387 errcnt = 0; 398 388 399 pthread_mutex_lock(&ringbuf.lock);389 ringbuf.lock.lock(); 400 390 ringbuf.used += len; 401 391 used = ringbuf.used; 402 392 ringbuf.writePtr += len; 403 pthread_mutex_unlock(&ringbuf.lock);393 ringbuf.lock.unlock(); 404 394 405 395 #ifdef REPORT_RING_STATS 406 pthread_mutex_lock(&ringbuf.lock_stats);396 ringbuf.lock_stats.lock(); 407 397 408 398 if (ringbuf.max_used < used) 409 399 ringbuf.max_used = used; 410 400 411 401 ringbuf.avg_used = ((ringbuf.avg_used * ringbuf.avg_cnt) + used) 412 402 / ++ringbuf.avg_cnt; 413 pthread_mutex_unlock(&ringbuf.lock_stats); 403 404 ringbuf.lock_stats.unlock(); 414 405 #endif 415 406 416 407 if (ringbuf.writePtr == ringbuf.endPtr) … … 432 423 bool dev_error = false; 433 424 bool dev_eof = false; 434 425 435 pthread_mutex_lock(&ringbuf.lock);426 ringbuf.lock.lock(); 436 427 avail = ringbuf.used; 437 pthread_mutex_unlock(&ringbuf.lock);428 ringbuf.lock.unlock(); 438 429 439 430 min_read = cnt < ringbuf.min_read ? cnt : ringbuf.min_read; 440 431 … … 445 436 if (request_pause || dev_error || dev_eof) 446 437 return 0; 447 438 448 pthread_mutex_lock(&ringbuf.lock); 439 QMutexLocker locker(&ringbuf.lock); 440 449 441 dev_error = ringbuf.error; 450 442 dev_eof = ringbuf.eof; 451 443 avail = ringbuf.used; 452 pthread_mutex_unlock(&ringbuf.lock);453 444 } 454 445 if (cnt > avail) 455 446 cnt = avail; … … 475 466 ringbuf.readPtr += cnt; 476 467 } 477 468 478 pthread_mutex_lock(&ringbuf.lock);469 ringbuf.lock.lock(); 479 470 ringbuf.used -= cnt; 480 pthread_mutex_unlock(&ringbuf.lock);471 ringbuf.lock.unlock(); 481 472 482 473 if (ringbuf.readPtr == ringbuf.endPtr) 483 474 ringbuf.readPtr = ringbuf.buffer; … … 488 479 489 480 if (++loop == report_loops) 490 481 { 482 QMutexLocker locker(&ringbuf.lock_stats); 483 491 484 loop = 0; 492 pthread_mutex_lock(&ringbuf.lock_stats);493 485 avg = ringbuf.avg_used; 494 486 samples = ringbuf.avg_cnt; 495 487 max = ringbuf.max_used; 496 488 ringbuf.avg_used = 0; 497 489 ringbuf.avg_cnt = 0; 498 490 ringbuf.max_used = 0; 499 pthread_mutex_unlock(&ringbuf.lock_stats);500 491 501 492 VERBOSE(VB_IMPORTANT, QString("%1 ringbuf avg %2% max %3%" 502 493 " samples %4") … … 582 573 // TRANSFER DATA 583 574 while (_request_recording) 584 575 { 585 pthread_mutex_lock(&ringbuf.lock);576 ringbuf.lock.lock(); 586 577 dev_error = ringbuf.error; 587 578 dev_eof = ringbuf.eof; 588 579 pause = ringbuf.paused; 589 pthread_mutex_unlock(&ringbuf.lock);580 ringbuf.lock.unlock(); 590 581 591 582 if (request_pause) 592 583 { 593 pthread_mutex_lock(&ringbuf.lock);584 ringbuf.lock.lock(); 594 585 ringbuf.request_pause = true; 595 pthread_mutex_unlock(&ringbuf.lock);586 ringbuf.lock.unlock(); 596 587 597 588 usleep(1000); 598 589 continue; 599 590 } 600 591 else if (pause) 601 592 { 602 pthread_mutex_lock(&ringbuf.lock);593 ringbuf.lock.lock(); 603 594 ringbuf.request_pause = false; 604 pthread_mutex_unlock(&ringbuf.lock);595 ringbuf.lock.unlock(); 605 596 606 597 usleep(1500); 607 598 continue; … … 646 637 647 638 _request_recording = false; 648 639 649 pthread_mutex_lock(&ringbuf.lock);640 ringbuf.lock.lock(); 650 641 bool run = ringbuf.run; 651 642 ringbuf.run = false; 652 pthread_mutex_unlock(&ringbuf.lock);643 ringbuf.lock.unlock(); 653 644 654 645 if (run) 655 646 pthread_join(ringbuf.thread, NULL); … … 669 660 670 661 void HDTVRecorder::Pause(bool /*clear*/) 671 662 { 672 pthread_mutex_lock(&ringbuf.lock);663 ringbuf.lock.lock(); 673 664 ringbuf.paused = false; 674 pthread_mutex_unlock(&ringbuf.lock);665 ringbuf.lock.unlock(); 675 666 request_pause = true; 676 667 } 677 668 678 669 bool HDTVRecorder::IsPaused(void) const 679 670 { 680 pthread_mutex_lock(&ringbuf.lock);671 ringbuf.lock.lock(); 681 672 bool paused = ringbuf.paused; 682 pthread_mutex_unlock(&ringbuf.lock);673 ringbuf.lock.unlock(); 683 674 684 675 return paused; 685 676 } … … 900 891 } 901 892 else 902 893 { 903 pthread_mutex_lock(&ringbuf.lock);894 QMutexLocker locker(&ringbuf.lock); 904 895 ringbuf.used = 0; 905 896 ringbuf.max_used = 0; 906 897 ringbuf.readPtr = ringbuf.writePtr = ringbuf.buffer; 907 pthread_mutex_unlock(&ringbuf.lock);908 898 } 909 899 Unpause(); 910 900 } -
fifowriter.cpp
32 32 fb_inptr = new struct fifo_buf *[count]; 33 33 fb_outptr = new struct fifo_buf *[count]; 34 34 fifothrds = new pthread_t[count]; 35 fifo_lock = new pthread_mutex_t [count]; 36 empty_cond = new pthread_cond_t[count]; 37 full_cond = new pthread_cond_t[count]; 38 for (int i = 0; i < count; i++) 39 { 40 pthread_cond_init(&empty_cond[i], NULL); 41 pthread_cond_init(&full_cond[i], NULL); 42 } 35 fifo_lock = new QMutex[count]; 36 empty_cond = new QWaitCondition[count]; 37 full_cond = new QWaitCondition[count]; 43 38 filename = new QString [count]; 44 39 fbdesc = new QString [count]; 45 40 } … … 49 44 for (int i = 0; i <num_fifos; i++) 50 45 { 51 46 killwr[i] = 1; 52 pthread_cond_signal(&empty_cond[i]); 47 48 fifo_lock[i].lock(); 49 empty_cond[i].wakeOne(); 50 fifo_lock[i].unlock(); 51 53 52 pthread_join(fifothrds[i], NULL); 54 53 } 55 54 delete [] maxblksize; … … 59 58 delete [] fifothrds; 60 59 delete [] full_cond; 61 60 delete [] empty_cond; 61 delete [] fifo_lock; 62 62 delete [] filename; 63 63 delete [] fbdesc; 64 64 delete [] killwr; … … 95 95 } 96 96 fb_inptr[id] = fifo_buf[id]; 97 97 fb_outptr[id] = fifo_buf[id]; 98 pthread_mutex_init(&fifo_lock[id], NULL);99 98 100 99 cur_id = id; 101 100 … … 120 119 { 121 120 int id = cur_id; 122 121 int fd = -1; 123 pthread_mutex_lock(&fifo_lock[id]);122 fifo_lock[id].lock(); 124 123 cur_id = -1; 125 124 while (1) 126 125 { 127 126 if (fb_inptr[id] == fb_outptr[id]) 128 pthread_cond_wait(&empty_cond[id],&fifo_lock[id]);129 pthread_mutex_unlock(&fifo_lock[id]);127 empty_cond[id].wait(&fifo_lock[id]); 128 fifo_lock[id].unlock(); 130 129 if (killwr[id]) 131 130 break; 132 131 if (fd == -1) 133 132 fd = open(filename[id].ascii(), O_WRONLY| O_SYNC); 134 133 write(fd, fb_outptr[id]->data, fb_outptr[id]->blksize); 135 pthread_mutex_lock(&fifo_lock[id]);134 fifo_lock[id].lock(); 136 135 fb_outptr[id] = fb_outptr[id]->next; 137 pthread_cond_signal(&full_cond[id]);136 full_cond[id].wakeOne(); 138 137 } 139 138 140 139 if (fd != -1) … … 155 154 156 155 void FIFOWriter::FIFOWrite(int id, void *buffer, long blksize) 157 156 { 158 pthread_mutex_lock(&fifo_lock[id]);157 fifo_lock[id].lock(); 159 158 while (fb_inptr[id]->next == fb_outptr[id]) 160 159 { 161 160 bool blocking = false; … … 183 182 } 184 183 else 185 184 { 186 struct timespec timeout; 187 struct timeval now; 188 gettimeofday(&now, NULL); 189 timeout.tv_sec = now.tv_sec + 1; 190 timeout.tv_nsec = now.tv_usec * 1000; 191 pthread_cond_timedwait(&full_cond[id], &fifo_lock[id], &timeout); 185 full_cond[id].wait(&fifo_lock[id], 1000); 192 186 } 193 187 } 194 188 if (blksize > maxblksize[id]) … … 199 193 memcpy(fb_inptr[id]->data,buffer,blksize); 200 194 fb_inptr[id]->blksize = blksize; 201 195 fb_inptr[id] = fb_inptr[id]->next; 202 pthread_cond_signal(&empty_cond[id]);203 pthread_mutex_unlock(&fifo_lock[id]);196 empty_cond[id].wakeOne(); 197 fifo_lock[id].unlock(); 204 198 } 205 199 206 200 void FIFOWriter::FIFODrain(void) … … 214 208 if (fb_inptr[i] == fb_outptr[i]) 215 209 { 216 210 killwr[i] = 1; 217 pthread_cond_signal(&empty_cond[i]); 211 fifo_lock[i].lock(); 212 empty_cond[i].wakeOne(); 213 fifo_lock[i].unlock(); 218 214 count++; 219 215 } 220 216 } -
fifowriter.h
4 4 #include <vector> 5 5 #include <qstring.h> 6 6 #include <qmutex.h> 7 #include <qwaitcondition.h> 7 8 #include <qptrqueue.h> 8 9 9 10 #include "mythexp.h" … … 32 33 } **fifo_buf, **fb_inptr, **fb_outptr; 33 34 34 35 pthread_t *fifothrds; 35 pthread_mutex_t*fifo_lock;36 pthread_cond_t*full_cond, *empty_cond;36 QMutex *fifo_lock; 37 QWaitCondition *full_cond, *empty_cond; 37 38 38 39 QString *filename, *fbdesc; 39 40