Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating a spawn blocks application closure #37

Open
matkuki opened this issue Nov 24, 2024 · 7 comments
Open

Creating a spawn blocks application closure #37

matkuki opened this issue Nov 24, 2024 · 7 comments

Comments

@matkuki
Copy link

matkuki commented Nov 24, 2024

Hi,

  • Windows 10 x64
  • Nim almost devel
  • malebolgia: nimble install malebolgia
  • niup: nimble install niup

I have a niup application that uses malebolgia to spawn a sound effect in a {.cdecl.} callback. This is the callback:

import malebolgia
import niup
import soundutils

var
    ...
    malebolgia_master = malebolgia.createMaster()
    malebolgia_results = newSeq[PlaybackResult](10)

niup.init()

...

# Countdown timer callback
proc countdown_tick(arg: PtrIhandle): cint {.cdecl.} =
    const filename = "alarm.wav"
    malebolgia_master.awaitAll:
        malebolgia_master.spawn soundutils.play_wav(filename) -> malebolgia_results[0]
    echo "Sound playback completed."

...

main_window.showXY(IUP_CENTER, IUP_CENTER)

niup.mainLoop()
niup.close()

echo "Application closed."

Now, running the application and closing it without the callback countdown_tick not being executed: no problems, application closes.
But running it and executing the callback, everything is fine, the soundutils.play_wav spawning works great and "Sound playback completed." is echoed, but closing the application echo's "Application closed." and then hangs indefinitely, until Ctrl+C is pressed.
If I change the callback to a synchronous execution, like so:

proc countdown_tick(arg: PtrIhandle): cint {.cdecl.} =
    const filename = "alarm.wav"
    let result = soundutils.play_wav(filename)
    echo "Sound playback completed."

... it also works without problems.

Any ideas of what's blocking the closing of the application when a spawn is created?

P.S.:
I tried adding malebolgia_master.cancel() at the end after the echo, no difference.
Also tried malebolgia.panicStop(), but that call itself also hangs indefinitely.

@matkuki matkuki changed the title creating a spawn blocks application closure Creating a spawn blocks application closure Nov 24, 2024
@Araq
Copy link
Owner

Araq commented Nov 25, 2024

What does valgrind say?

@matkuki
Copy link
Author

matkuki commented Nov 25, 2024

I'm on Windows, any simple way to install valgrind on it?
I have Visual Studio 2022, if maybe I can give you some information with it?

@matkuki
Copy link
Author

matkuki commented Nov 25, 2024

@Araq
Note that the code has no main function, all of it is directly in the file. which looks roughly like this:

all imports
...

niup.open()

all variable and callback definitions
...

main_window.showXY(IUP_CENTER, IUP_CENTER)

niup.mainLoop()

niup.close()

malebolgia.panicStop() # <- THIS HANGS FOREVER!

echo "END"

Added echo's into the panicStop() call ( the call added at the bottom of the code) and it stops here:

proc panicStop*() =
  ## Stops all threads.
  echo 1
  globalStopToken.store(true, moRelaxed)
  echo 2
  joinThreads(thr) # <- HANGS HERE!
  echo 3
  deinitCond(chan.dataAvailable)
  echo 4
  deinitCond(chan.spaceAvailable)
  echo 5
  deinitLock(chan.L)
  echo 6

@matkuki
Copy link
Author

matkuki commented Nov 27, 2024

@Araq
The joinThreads line inside panicStop always blocks, even when not spawning anything.
I assume it's a Windows issue with joinThreads. Is there an issue for this already open in Nim's repository?

@Araq
Copy link
Owner

Araq commented Nov 27, 2024

Pretty sure it's something else, joinThreads is used heavily, even on Windows.

@matkuki
Copy link
Author

matkuki commented Dec 11, 2024

Hey @Araq
If I change this in malebolgia.nim:
slika
... to this:
slika
... it works!
Any ideas?

P.S.:
Any number higher than 1 for ThreadPoolSize makes it hang, only 1 works.

@Araq
Copy link
Owner

Araq commented Dec 11, 2024

Yeah well, you need to setup WSL and run it via valgrind under Linux. Most likely one of your dependencies doesn't play nice and it's the most reasonable way to debug these things.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants