For some users on poor connections, toxav would suggest lower and lower bitratres until reaching zero and disabling audio/video entirely, toxav would then not raise the bitrate back and the only way to re-enable audio/video would have been to change A/V sources or restart the call
We now log toxav's recommendation, but ignore it
Could only be hit by pausing at a key point in a debugger until the call timed-out.
Having one thread going up the call stack and acquiring locks (toxcore callbacks), while another thread goes down taking locks in the other order (CoreAV calling toxav functions) creates some pretty freezy situations.
The deadlock was caused by the GUI thread calling the CoreAV thread, acquiring the CoreAV callback, then right before calling a toxav function, not schedule the thread until the call times out. At this point the toxcore thread fires its state callback to tell us the call is over, locking internal toxcore/toxav mutexes, it reaches our callback function which tries to switch to the CoreAV thread to clean up the call data structures, but has to wait since the CoreAV thread holds its own lock. At this point if we resume the CoreAV thread, it'll be busy calling into a toxav function, which tries to acquire internal toxav locks, those locks are held by the toxcore callback so we deadlock.
Our solution is that when getting a toxcore callback, we immediately switch to a temporary thread, allowing toxcore to release the locks it held, and that temporary thread tries to switch to do work on call data structures. Meanwhile if the CoreAV thread needs internal toxcore locks, it can get them.
A call cancel/accepted race was locking up both UI and AV threads, while the stream thread was shoveling more and more video frames on the AV thread's event queue
This error condition only happens when a peer cancels its outgoing call in the middle of us answering it. We can simply ignore the error and things should nicely fall back into place. Since this race should be pretty rare in normal usage, it's nice to leave a log message, as it might mean we're being fuzzed.
We can prograssively replace more of those asserts by fallbacks and log messages now that everything has been shown to work fine, and the race conditions are harmless.
I feel like writing a novel today. Good thing nobody looks at these!
And properly handle toxav happily delivering things out of order,
like firing a video frame callback right after a callback setting the bitrate to 0,
when the peer sent these commands in the right order
A race condition would result in trying to remove an element that didn't exist, and thus erasing end (undefined behavior) instead of erasing [end, end) (no-op)
That pull request made qTox crash in a number of ways, with no quick fix
available.
Hopefully there will be a way to fix crash, so that this commit could be
reverted, and fix applied.
And make it saner by not having one global password that has to be set before encrypting/decrypting, which is as racy and poorly designed as it gets
Fixes#1917 's immediate symtoms, which some potential for other regressions due to the mess that is encrypted persistence currently
There can now only be one CameraSource running.
Video frames are decoded in their own thread, and then converted by users in the user's threads.
The CameraSource API is entirely thread-safe and controls the video decoding thread.
The video device only stays open as long as there are users subscribed to the CameraSource.
We use a dangerous combination of spinlocks and memory fences to keep things synchronized.
We now use a binary serialized format to save space and allow clean encryption of the user settings.
All the settings can (and should) be edited from the GUI so there is no loss of functionnality.
It can still read the old .ini format, and will seamlessly upgrade to the new format.
Fixes#1810
The qTox Project is not associated with the Tox Project in any way, with the
exception of "qTox" using the Tox Projet's "toxcore" collection of libraries.
In particular, the Tox Projet does not own copyright over the qTox Project's
"qTox" collection of software, source code, and assets.
The qTox Project's assets are under the sole copyright of the qTox
contributors, and no partiular rights are granted to the Tox Project.
Since consistency in code is most important, 'ToxId' is used
for code, whereas 'Tox ID' anywhere outside of code.
Also fixed wrong comments in core.h:
* qTox gets only public key of a grouchat peer, not their
Tox ID
* qTox tries to return full address (Tox ID) or public key
The qTox Project is not associated with the Tox Project in any ways, with the exception of "qTox" using the Tox Projet's "toxcore" collection of libraries.
In particular, the Tox Projet does not own copyright over the qTox Project's "qTox" collection of software, source code, and assets.
The qTox Project's assets are under the sole copyright of the qTox contributors, and no partiular rights are granted to the Tox Project.
They were suffering from double-connection syndrom, and the way muting worked was now conflicting with how the output sound level setting works
Fixes#1442
By reducing the maximum interval between two tox_iterate calls during file transfers to 10ms. This results in reasonnable amounts of extra CPU% used. If the only file transfers are avatars, CoreFile allows sleeping for up to 50ms. If there are currently no FT, up to 1000ms.
We now take the minimum sleeping interval asked by toxcore, toxav, and CoreFile
Load the setting's cameria preview opengl context lazily and destroy it when done. Only preallocte Core's video buffer if we have any calls active, free up when all calls are done
Toxcore would incorrectly report the call as a video call in the call settings, and then crash while trying to send a video frame in the audio call. We workaround that by using another API that correctly reports the type of the call
askProfiles is a really dangerous function. Awful things happen when the user closes that message box. We now prevent it from being closed in more places
There are small instants on startup and while profile switching during which no profile is loaded but the GUI could still receive events, e.g. between two modal windows. Disable the GUI to prevent that.
Don't just let the user close the profile select box and continue with an empty value. We would create a new profile and save it back on top of the previous encrypted profile
- Add AvatarBroadcaster, in charge of making sure our friends have our avatar without spamming file transfers
- Fix file sending code not closing the file after transfer, which prevented file previews, and make the QFile a shared_ptr to fix the obvious memory leak
Some small additions to Core to support AvatarBroadcaster
This fixes the potential edge case where a frozen then unfrozen qTox instance could have its locks delete by a new qTox instance.
We now check that we still own our locks, restoring them if we can, before saving
Starting a new instance with the -p option will force it to start a new instance with the given profile instead of bringing an eventual existing instance to the foreground
Two instances can not run with the same profiles, the profile locking code will ensure that. A user who likes to live dangerously could manually delete the lock to force two instances on the same profile, but such an hypothetical user would be asking for it.
If a qTox instance starts and becomes owner of the IPC shared memory on its first try, it considers itself the only running freshly-started instance, and deletes any possibly stale lock before starting up. This should be fine in the vast majority of cases, but if an existing qTox instance freezes for a long enough time to lose ownership of the IPC and a new instance is started without first killing the frozen one, the frozen instance's lock will be deleted as stale by the new one. If the frozen instance subsequentely unfreezes, it will be running on a profile for which it doesn't have a lock, which could cause trouble. This is an intentionaly allowed edge case, the alternative being a stale lock staying forever until removed manually. A potential solution not yet implemented would be to check that the lock is still actually present before attempting any write.