3 |
* LinuxSampler - modular, streaming capable sampler * |
* LinuxSampler - modular, streaming capable sampler * |
4 |
* * |
* * |
5 |
* Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck * |
* Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck * |
6 |
* Copyright (C) 2005 - 2008 Christian Schoenebeck * |
* Copyright (C) 2005 - 2020 Christian Schoenebeck * |
7 |
* Copyright (C) 2009 - 2012 Christian Schoenebeck and Grigor Iliev * |
* Copyright (C) 2009 - 2012 Grigor Iliev * |
8 |
* Copyright (C) 2013 - 2016 Christian Schoenebeck and Andreas Persson * |
* Copyright (C) 2013 - 2016 Andreas Persson * |
9 |
* * |
* * |
10 |
* This program is free software; you can redistribute it and/or modify * |
* This program is free software; you can redistribute it and/or modify * |
11 |
* it under the terms of the GNU General Public License as published by * |
* it under the terms of the GNU General Public License as published by * |
456 |
// Implementation of virtual method from class Thread |
// Implementation of virtual method from class Thread |
457 |
int Main() { |
int Main() { |
458 |
dmsg(3,("Disk thread running\n")); |
dmsg(3,("Disk thread running\n")); |
459 |
|
|
460 |
|
#if DEBUG |
461 |
|
Thread::setNameOfCaller("DiskIO"); |
462 |
|
#endif |
463 |
|
|
464 |
while (true) { |
while (true) { |
465 |
#if !defined(WIN32) |
|
|
pthread_testcancel(); // mandatory for OSX |
|
|
#endif |
|
|
#if CONFIG_PTHREAD_TESTCANCEL |
|
466 |
TestCancel(); |
TestCancel(); |
467 |
#endif |
|
468 |
IsIdle = true; // will be set to false if a stream got filled |
IsIdle = true; // will be set to false if a stream got filled |
469 |
|
|
470 |
|
// prevent disk thread from being cancelled |
471 |
|
// (e.g. to prevent deadlocks while holding mutex lock(s)) |
472 |
|
pushCancelable(false); |
473 |
|
|
474 |
// if there are ghost streams, delete them |
// if there are ghost streams, delete them |
475 |
for (int i = 0; i < GhostQueue->read_space(); i++) { //FIXME: unefficient |
for (int i = 0; i < GhostQueue->read_space(); i++) { //FIXME: unefficient |
476 |
delete_command_t ghostStream; |
delete_command_t ghostStream; |
532 |
|
|
533 |
RefillStreams(); // refill the most empty streams |
RefillStreams(); // refill the most empty streams |
534 |
|
|
|
// if nothing was done during this iteration (eg no streambuffer |
|
|
// filled with data) then sleep for 30ms |
|
|
if (IsIdle) usleep(30000); |
|
|
|
|
535 |
int streamsInUsage = 0; |
int streamsInUsage = 0; |
536 |
for (int i = Streams - 1; i >= 0; i--) { |
for (int i = Streams - 1; i >= 0; i--) { |
537 |
if (pStreams[i]->GetState() != Stream::state_unused) streamsInUsage++; |
if (pStreams[i]->GetState() != Stream::state_unused) streamsInUsage++; |
538 |
} |
} |
539 |
SetActiveStreamCount(streamsInUsage); |
SetActiveStreamCount(streamsInUsage); |
540 |
if (streamsInUsage > ActiveStreamCountMax) ActiveStreamCountMax = streamsInUsage; |
if (streamsInUsage > ActiveStreamCountMax) ActiveStreamCountMax = streamsInUsage; |
541 |
|
|
542 |
|
// now allow disk thread being cancelled again |
543 |
|
// (since all mutexes are now unlocked and data structures |
544 |
|
// are at consistent states) |
545 |
|
popCancelable(); |
546 |
|
|
547 |
|
// if nothing was done during this iteration (i.e. no |
548 |
|
// stream buffer filled with data) then sleep for 30ms |
549 |
|
if (IsIdle) |
550 |
|
usleep(30000); //NOTE: defined as cancellation point by POSIX |
551 |
} |
} |
552 |
|
|
553 |
return EXIT_FAILURE; |
return EXIT_FAILURE; |