Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » U++ Library support » U++ MT-multithreading and servers » ASyncWork/CoWork Cancel() method leads to deadlock (when used with GuiLock)
ASyncWork/CoWork Cancel() method leads to deadlock (when used with GuiLock) [message #50203] Sun, 26 August 2018 20:16 Go to next message
Oblivion is currently offline  Oblivion
Messages: 556
Registered: August 2007
Location: Turkey
Contributor
Hello,

This happens on both linux (latest) and Window 7/10.

When I try to cancel any AsyncWork/CoWork-based threads that access/modify gui elements (using GuiLock) application simply hangs.
(OTOH, If i use a simple cancelleation flag instead, everything works well. But obviously it work like a "cancel all" command)

I attached a simple example, and here is its log:

CoWork constructed 7f66af217ca0
Do0, looper: false, previous todo: 0
Pool::InitThreads: 8
CoWork thread #0 started
CoWork thread #1 started
CoWork thread #2 started
CoWork thread #4 started
CoWork thread #3 started
CoWork thread #5 started
CoWork thread #6 started
CoWork thread #7 started
#2 Waiting for job
#5 Waiting for job
#0 Waiting for job
#4 Waiting for job
#1 Waiting for job
#7 Waiting for job
#3 Waiting for job
#6 Waiting for job
Adding job
Releasing thread waiting for job, waiting threads: 8
#2 Waiting ended
#2 Job acquired
CoWork constructed 7f66af217d80
DoJob (CoWork 7f66af217ca0)
Thread #0 started.
Do0, looper: false, previous todo: 0
Adding job
Releasing thread waiting for job, waiting threads: 7
CoWork constructed 7f66af217e60
#5 Waiting ended
#5 Job acquired
DoJob (CoWork 7f66af217d80)
Thread #1 started.
Do0, looper: false, previous todo: 0
Adding job
Releasing thread waiting for job, waiting threads: 6
#0 Waiting ended
#0 Job acquired
CoWork constructed 7f66af217f40
DoJob (CoWork 7f66af217e60)
Thread #2 started.
Do0, looper: false, previous todo: 0
Adding job
Releasing thread waiting for job, waiting threads: 5
#4 Waiting ended
#4 Job acquired
DoJob (CoWork 7f66af217f40)
Thread #3 started.
CoWork Cancel0
WaitForFinish (CoWork 7f66af217ca0)


What am I doing wrong?

Best regards,
Oblivion

[Updated on: Sun, 26 August 2018 20:19]

Report message to a moderator

Re: ASyncWork/CoWork Cancel() method leads to deadlock (when used with GuiLock) [message #50205 is a reply to message #50203] Mon, 27 August 2018 09:47 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 11844
Registered: November 2005
Ultimate Member
I believe the issue is caused by the fact that "Cancel" waits for the job to actually exit.

Now AsyncTest::Stop is GUI event, so when it performs, GuiLock is locked. Cancel has to wait for CoWork to finish - that is important, because often CoWork jobs are referencing local data. Then in your worker job, you attempt to GuiLock too. Obviously, after that Sleep, it is unable to lock GuiLock and result is deadlock.

Now what to do with that, I am not sure... Perhaps we need another form of 'Cancel' (something like 'Abandon') that is not required to wait for job to finish?
Re: ASyncWork/CoWork Cancel() method leads to deadlock (when used with GuiLock) [message #50206 is a reply to message #50205] Mon, 27 August 2018 09:55 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 11844
Registered: November 2005
Ultimate Member
After further thinking, 'Abandon' is dangerous idea. Perhaps we need something like 'GuiUnlock __' instead...

Mirek
Re: ASyncWork/CoWork Cancel() method leads to deadlock (when used with GuiLock) [message #50207 is a reply to message #50206] Mon, 27 August 2018 10:00 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 11844
Registered: November 2005
Ultimate Member
OK, fixed with GuiUnLock :

void AsyncTest::Stop()
{
	GuiUnLock __;
	for(auto& w : workers)
		w.Cancel();
}
Re: ASyncWork/CoWork Cancel() method leads to deadlock (when used with GuiLock) [message #50209 is a reply to message #50207] Mon, 27 August 2018 11:45 Go to previous messageGo to next message
Oblivion is currently offline  Oblivion
Messages: 556
Registered: August 2007
Location: Turkey
Contributor
Quote:

OK, fixed with GuiUnLock


Thanks, a very simple and nice solution!

However I'd recommend changing the class name from GuiUnLock to GuiUnlock. (It is easier to spell, and more natural.)

Best regards,
Oblivion
Re: ASyncWork/CoWork Cancel() method leads to deadlock (when used with GuiLock) [message #50212 is a reply to message #50209] Mon, 27 August 2018 17:24 Go to previous messageGo to next message
Klugier is currently offline  Klugier
Messages: 615
Registered: September 2012
Location: Poland, Kraków
Contributor
Hello Mirek

Why not make "n" private in GuiUnlock class:
struct GuiUnlock {
	int n; // There is realy not need to make it publicly available.
	
	 GuiUnlock()  { n = LeaveGuiMutexAll(); }
	~GuiUnlock() { EnterGuiMutex(n); }
};


Sincerely,
Klugier


Ultimate++ - one framework to rule them all.

[Updated on: Mon, 27 August 2018 17:24]

Report message to a moderator

Re: ASyncWork/CoWork Cancel() method leads to deadlock (when used with GuiLock) [message #50213 is a reply to message #50212] Mon, 27 August 2018 17:52 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 11844
Registered: November 2005
Ultimate Member
Yes, you are right.
Re: ASyncWork/CoWork Cancel() method leads to deadlock (when used with GuiLock) [message #50224 is a reply to message #50213] Tue, 28 August 2018 17:25 Go to previous message
mdelfede is currently offline  mdelfede
Messages: 1259
Registered: September 2007
Senior Contributor
I stumbled many times on this problem (mostly when calling inside a thread, like Ctrl::Call() )
and always solved with LeaveGuiMutexAll().
The new way is obviously better!
Previous Topic: [SOLVED] Discord bot 404 error using WebSocket, any ideas?
Next Topic: Windows authenticated web page load
Goto Forum:
  


Current Time: Thu Apr 25 11:49:01 CEST 2019

Total time taken to generate the page: 0.01643 seconds