Skip to main content
gamedev.net
🔒 Locked

Multiple windows deadlock?

Started by xlad Sep 12, 2010 at 6:58 AM 1 replies 1.2k views
Original Post
xlad
xlad
I have a window class, which handles a window in it's own thread (1 window with 1 thread). The window proc is made "static", so it doesn't know which is the window that received messages, and i added a container class to solve this problem.

When i launch the application, everything works fine, but some moments later (randomly between 0 and 3 minutes), some windows just stop responding. I stripped the windowProc, and left only defwindowproc and the windowcontainer.getowner and the problems still exists, but if i leave only defwindowproc, the windows never become nonresponsive.

This means the problem is in WindowsContainer.

When i make a call of WindowContainer(getowner, addwindow, deletewindow), i enter in it's own critical section, do what i need, then i leave the critical section.

Why do the windows stop responding? (deadlocks?) And there is a way to fix it?
I'm using Win32 API.

P.S. in the virtual pc (where i write my application) this doesn't happen, and on my friend's pc too. But it seems to happen on my pc (which has a dual core CPU - hyper threading)

class TThread{ private : public :  virtual void Execute(void); // what a thread is executing};class TWindowContainer{ private :  CRITICALSECTION mycs; public :  constructor  void addwindow(int threadid,pointer parent);  void deletewindow(int threadid);  pointer getowner(int threadid);};void TWindowContainer::addwindow(...){ mycs.enter(); add it; mycs.leave();}void TWindowContainer::deletewindow(...){ mycs.enter(); delete it; mycs.leave();}pointer TWindowContainer::getowner(...){ mycs.enter(); value = get it mycs.leave(); return value;}TWindowsContainer WindowContainer;//it is only in the basicwindow.cpp, not globaltypedef TWindow *PWindow;class TWindow{ private :  class TWThread : public TThread   {    public :     PWindow Parent;     void Execute(void);   };  TWThread OwnThread;  friend ... WindowProc(...); public :  constructor; // OwnThread.Parent = this;  destructor;  other functions;};... WindowProc(...){ PWindow Owner = WindowsContainer.GetOwner(GetCurrentThreadId()); // uses criticalsection if (Owner != null)   {    do something    return 0; / return TRUE;   } return defwindowproc(...);}void TWindow::TWThread::Execute(void){ WindowsContainer.AddWindow(GetCurrentThreadId(),Parent); // uses criticalsection createwindowEx(...); if (failed)   {    WindowsContainer.deletewindow(...); // uses criticalsection    return;   } while (Terminated() == False)  {   peekmessage   translatemessage   dispatchmessgae //WindowProc is called here  } WindowsContainer.deletewindow(...); // uses criticalsection}
Jansic
Jansic
Most likely you're not calling defwindowproc for messages that you aren't handling. You can't catch system messages and just ignore them.

More to the point, remove this thread locking insanity:- Pass the window class's 'this' pointer via CreateWindowEx's lpParam argument and catch it in the WM_NCCREATE message in the handler. You can then stash it into the window's GWLP_USERDATA slot using SetWindowLongPtr. Retrieve it for subsequent messages using GetWindowLongPtr.

On another note, running windows on their own threads can cause all sorts of headaches. You can't parent a window created on one thread with a window created on a different thread and expect sensible results.

Jans.

xlad
xlad
Quote:
Original post by Jansic
Most likely you're not calling defwindowproc for messages that you aren't handling. You can't catch system messages and just ignore them.


Any message that i do not handle is sent to defwindowproc. This isn't the problem.

Quote:

More to the point, remove this thread locking insanity:- Pass the window class's 'this' pointer via CreateWindowEx's lpParam argument and catch it in the WM_NCCREATE message in the handler. You can then stash it into the window's GWLP_USERDATA slot using SetWindowLongPtr. Retrieve it for subsequent messages using GetWindowLongPtr.


I found this method some time ago, but didn't read the CreateWindowEx msdn page about the lParam, and i was thinking when the windows was created, that i can't find the owner through USERDATA. I think with the lParam might work.

Quote:

On another note, running windows on their own threads can cause all sorts of headaches. You can't parent a window created on one thread with a window created on a different thread and expect sensible results.

Jans.


I don't want to make a MDI application (parent and child windows), i want to have separate windows, each running on it's own, so it is ok for me to have it as it is now.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.