www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Thread exits immediately with no reason.

reply solidstate1991 <laszloszeremi outlook.com> writes:
Here's this function, which serves as a thread entry point: 
https://github.com/ZILtoid1991/iota/blob/main/source/iota/audio/wasapi.d#L220

The problem is, that even with disabling all error-handling that 
would allow to shut down the thread safely, the thread only runs 
that while loop once.

However, if I set my debugger to have a breakpoint right at the 
loop entry it can kinda loop, however the real-time capabilities 
cease to work properly.

I'm using this handy application to debug my library: 
https://github.com/ZILtoid1991/iota/blob/main/testsource/app.d#L54

After the referenced line (where I start my audio thread) I also 
set the main program to wait 10 seconds. At least the audio 
thread just exits for some reason instead of being suspended by 
Thread.wait().
Dec 20 2021
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 12/20/21 3:56 PM, solidstate1991 wrote:

 The problem is, that even with disabling all error-handling that would
 allow to shut down the thread safely, the thread only runs that while
 loop once.
I bet it's throwing an Error. Call your thread entry function from a try-catch wrapping function to see whether that's the case: // Rename existing function: protected void audioThreadImpl() nogc nothrow { // ... } // New function protected void audioThread() nogc nothrow { try { audioThreadImpl(); } catch (Error err) { stderr.writefln!"ERROR: %s"(err); } } That should print a call stack. You can catch Throwable instead of Error but with nothrow, it's guaranteed that it's not an Exception. Note: nothrow means "does not throw Exception". Errors can still be thrown. Ali
Dec 20 2021
next sibling parent reply bauss <jj_1337 live.dk> writes:
On Tuesday, 21 December 2021 at 01:13:10 UTC, Ali Çehreli wrote:
 Note: nothrow means "does not throw Exception". Errors can 
 still be thrown.

 Ali
Which sort of makes sense since they're in theory "unrecoverable", but the name is sort of misleading because of this minor detail. It should at the very least warn people about functions that may throw errors.
Dec 20 2021
parent Dennis <dkorpel gmail.com> writes:
On Tuesday, 21 December 2021 at 07:08:53 UTC, bauss wrote:
 It should at the very least warn people about functions that 
 may throw errors.
What is "It"? I was looking to make a spec PR, but it already says here: https://dlang.org/spec/function.html#nothrow-functions
 Nothrow functions can only throw exceptions derived from class 
 Error.
Dec 21 2021
prev sibling parent reply solidstate1991 <laszloszeremi outlook.com> writes:
On Tuesday, 21 December 2021 at 01:13:10 UTC, Ali Çehreli wrote:
 I bet it's throwing an Error. Call your thread entry function 
 from a try-catch wrapping function to see whether that's the 
 case:

 // Rename existing function:
 protected void audioThreadImpl()  nogc nothrow {
   // ...
 }

 // New function
 protected void audioThread()  nogc nothrow {
   try {
     audioThreadImpl();

   } catch (Error err) {
     stderr.writefln!"ERROR: %s"(err);
   }
 }

 That should print a call stack. You can catch Throwable instead 
 of Error but with nothrow, it's guaranteed that it's not an 
 Exception.

 Note: nothrow means "does not throw Exception". Errors can 
 still be thrown.

 Ali
I couldn't add those lines unfortunately, but I do get an exception in a destructor at line 218 of `wasapi.d`. It's access violation executing a location.
Dec 21 2021
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 12/21/21 10:07 AM, solidstate1991 wrote:

 I couldn't add those lines unfortunately,
Perhaps I had typos? Or the code is not yours to modify? In any case, you should be able to introduce a top level thread entry function and put the try-catch in there.
 but I do get an exception in a
 destructor at line 218 of `wasapi.d`. It's access violation executing a
 location.
If garbage-collected objects are involved, it may be because destructors are executed at indeterminate times, potentially after their members are destroyed. I haven't studied the code to be sure but for example, eventHandle may have already been destroyed when executing the following line: https://github.com/ZILtoid1991/iota/blob/main/source/iota/audio/wasapi.d#L218 A solution is to manage the destruction of objects at known times e.g. by calling destroy() explicitly. Ali
Dec 21 2021
parent reply solidstate1991 <laszloszeremi outlook.com> writes:
Well, it seems like it's an error on the WASAPI side. I totally 
disabled error handling (including the switch-case thingy), then 
GetBuffer returns with an error code indicating buffer is too 
large.
Dec 21 2021
parent solidstate1991 <laszloszeremi outlook.com> writes:
On Tuesday, 21 December 2021 at 19:00:01 UTC, solidstate1991 
wrote:
 Well, it seems like it's an error on the WASAPI side. I totally 
 disabled error handling (including the switch-case thingy), 
 then GetBuffer returns with an error code indicating buffer is 
 too large.
The solution was to call `ResetEvent()` on the event handle, then to tinker a little bit with destructors, etc.
Dec 21 2021