This allows to call cancelPending() and waitAll() concurrently with no additional synchronization. While calling these two functions concurrently may not be useful often, supporting it costs little in terms of performance and code complexity. Furthermore, a completely thread-safe class is easier to document and use correctly. Optimize job finalization by notifying _waitVar only if jobsLeft is reduced to 0. Optimize cancelPending() by not locking jobsLeftMutex when no job is canceled (if the queue is empty when this function is called). Add assertions that verify invariants. The output of ConcurrentQueueTest::randomCalls() reflects the fact that a caller of waitAll() can be blocked indefinitely when another thread cancels all queued jobs while no job is being executed. The test output snippet below omits repetitive information: the "QINFO : ConcurrentQueueTest::randomCalls(queue{1}; 2 user thread(s))" prefix of each line, current thread id and the common hh:mm:ss current time part (leaving only the millisecond part). Note that thread #1 begins waiting at the 1st line of the snippet. "=> -8" means that total equals -8 and thus ConcurrentQueue::jobsLeft equals 8. Thread #0 then cancels all 8 queued jobs, then enqueues and cancels 3 jobs twice, then momentarily waits 3 times. #1 is not waked until #0 enqueues 8 more jobs and starts waiting for them too. Once these new 8 jobs are completed, both #0 and #1 end waiting. 1. [ms] 311 | #1 begin waiting for 1 thread => -8 2. [ms] 311 | #0 enqueuing complete. 3. [ms] 311 | #0 canceled 8 jobs => -8 4. [ms] 311 | #0 enqueuing 3 jobs... 5. [ms] 312 | #0 enqueuing complete. 6. [ms] 312 | #0 canceled 3 jobs => -3 7. [ms] 312 | #0 enqueuing 3 jobs... 8. [ms] 312 | #0 enqueuing complete. 9. [ms] 312 | #0 canceled 3 jobs => -3 10. [ms] 312 | #0 begin waiting for 1 thread => 0 11. [ms] 312 | #0 end waiting for 1 thread => 0 12. [ms] 312 | #0 begin waiting for 1 thread => 0 13. [ms] 312 | #0 end waiting for 1 thread => 0 14. [ms] 312 | #0 begin waiting for 1 thread => 0 15. [ms] 312 | #0 end waiting for 1 thread => 0 16. [ms] 312 | #0 canceled 0 jobs => 0 17. [ms] 312 | #0 canceled 0 jobs => 0 18. [ms] 312 | #0 enqueuing 3 jobs... 19. [ms] 312 | #0 enqueuing complete. 20. [ms] 312 | #0 enqueuing 3 jobs... 21. [ms] 312 | #0 enqueuing complete. 22. [ms] 312 | #0 enqueuing 2 jobs... 23. [ms] 312 | #0 enqueuing complete. 24. [ms] 312 | #0 begin waiting for 1 thread => -8 25. [ms] 312 | [0.1] sleep 0.003 ms... 26. [ms] 312 | [0.1] +1 => -7 27. [ms] 312 | [0.2] sleep 0.003 ms... 28. [ms] 312 | [0.2] +1 => -6 29. [ms] 312 | [0.3] sleep 0.003 ms... 30. [ms] 312 | [0.3] +1 => -5 31. [ms] 312 | [0.1] sleep 0 ms... 32. [ms] 313 | [0.1] +1 => -4 33. [ms] 313 | [0.2] sleep 0.005 ms... 34. [ms] 313 | [0.2] +1 => -3 35. [ms] 313 | [0.3] sleep 0 ms... 36. [ms] 313 | [0.3] +1 => -2 37. [ms] 313 | [0.1] sleep 0.001 ms... 38. [ms] 313 | [0.1] +1 => -1 39. [ms] 313 | [0.2] sleep 0.001 ms... 40. [ms] 313 | [0.2] +1 => 0 41. [ms] 313 | #0 end waiting for 1 thread => 0 42. [ms] 313 | #1 end waiting for 1 thread => 0 |
||
---|---|---|
ci/win | ||
common | ||
compressed_archive | ||
custom_widgets | ||
dependencies | ||
files | ||
images | ||
release | ||
shortcuts_management | ||
tests | ||
third_party | ||
YACReader | ||
YACReaderLibrary | ||
YACReaderLibraryServer | ||
.clang-format | ||
.editorconfig | ||
.gitattributes | ||
.gitignore | ||
azure-pipelines-build-number.yml | ||
azure-pipelines-windows-template-qt6.yml | ||
azure-pipelines-windows-template.yml | ||
azure-pipelines.yml | ||
background.png | ||
background@2x.png | ||
CHANGELOG.md | ||
cleanOSX.sh | ||
compileOSX.sh | ||
config.pri | ||
COPYING.txt | ||
dmg.json | ||
icon.icns | ||
INSTALL.md | ||
mktarball.sh | ||
README.md | ||
signapps.sh | ||
YACReader.1 | ||
YACReader.desktop | ||
YACReader.pro | ||
YACReader.svg | ||
YACReaderLibrary.1 | ||
YACReaderLibrary.desktop | ||
YACReaderLibrary.svg |
Build | Master | Develop |
---|---|---|
Code Validation | ||
Linux | ||
Windows x86 | ||
Windows x64 | ||
MacOS | ||
Publish Build |
YACReader
"Yet another comic reader"
License
This software has been developed by Luis Ángel San Martín Rodríguez (luisangelsm@gmail.com) under GPL v3 license (see COPYING.txt).
Getting YACReader
Official releases:
https://github.com/YACReader/yacreader/releases
As a package:
From OBS build service:
Building from source:
See INSTALL.md
Contact
- Project home page : www.yacreader.com
- e-mail:
- Social:
- Facebook - http://www.facebook.com/YACReader
- Twitter - https://twitter.com/yacreader
- YouTube - https://www.youtube.com/user/yacreader
- Instagram - https://www.instagram.com/yacreader/
If you need help or have any suggestion, please, send me an e-mail.
Contributing
If you are interested in contributing to the project the first step should be to contact me so we can plan together the best approach, you can send an e-mail or just open an issue in this repo. For small bug fixes it is usually ok to open a PR directly.
Contributions are not restricted to code, you can help the project by bringing new UI/UX ideas, designing new assets, writing manuals or tutorials, translating the apps, etc. If you are interested in DevOps, YACReader uses Azure Pipelines for CI/CD, any improvements in that area are welcome. Testing pre-releases is also really appreciated.
Code
YACReader uses clang-format
to ensure a common style and avoid deviances from it. CI checks this and will fail if the correct format is not used. clang-format
needs to be called recursively in all the folders because some of them have the own .clang-format
file, mainly to exclude changing the format in third-party libraries which are included in the source code. I recommend to configure your development tools to use clang-format
, you can try to use it manually, but please, do it always before committing changes. I recommend using QtCreator configured properly, you can find a tutorial here.
CI/CD
Any PR will be validated through CI, and it will not be merged if CI fails.
Pull Requests
The base and target branch for any PR should always be develop
.
Donations
YACReader is free but it needs money to keep being alive, so please, if you like YACReader, visit the home page and make a donation.