Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > winsock2 & wxWidgets: application hangs after reading UDP datagram,then accessing wxTextCtrl

Reply
Thread Tools

winsock2 & wxWidgets: application hangs after reading UDP datagram,then accessing wxTextCtrl

 
 
Lars Uffmann
Guest
Posts: n/a
 
      02-19-2008
X-Post to comp.unix.programmer & comp.lang.c++
F'Up set to comp.lang.c++

Hi everyone!

I am sorry that I am not able to reduce the bug-reproducing code
further, I have been trying to debug this for 2 days at least. What I am
doing is: I have a minimal wxWidgets application (GUI code as generated
by wxFormBuilder at the bottom) with a frame mainFrane, a wxBoxSizer
sizerMain, a wxTextCtrl txt1 and a wxButton cmd1. Now on wxApp::OnInit,
I start a boost::thread that listens for a UDP datagram. The cmd1 button
will send a simple UDP packet (just 1 byte, value 0) so the thread can
finish, then call a join() on the thread to wait for it to exit.

After that I want to access the properties of the wxTextCtrl txt1. In
this case txt1->GetValue(). The very function worked fine just before
the recvfrom call in my thread function. Right AFTER that call, when the
UDP packet has been received, the program locks up IF I try to access
txt1->GetValue(). txt1->GetName() works fine just in the line before. If
I do not call this function, the application is fine and can be exited
normally. If I do not call recvfrom, I can access txt1->GetValue() just
fine.

Now the really strange thing is: if I play back a "REAL" UDP packet,
like the ones I am writing this application for, everything works just
fine: the recvfrom gets called, gets (part of) the packet, and then the
call to txt1->GetValue() yields the expected result, and the application
is healthy.

So does this mean that my usage of the socket function sendto(...) is
wrong, and that it causes undefined behaviour to send a single byte with
value 0 in a UDP datagram?

Or if not - what could possibly be causing this lockup? Complete code
following, sorry for the X-Post, but since it's a problem that occurs
upon combined usage of the socket library & wxWidgets (and
boost:thread), I think it makes sense to ask in both relevant groups.
Unless of course its a winsock2 problem that would not occur with linux
sockets...

In the attached code, please search for the comment line that says
/* LOCKUP HERE */

To compile this example you'll need wxwidgets, boost::thread and the
sockets library for your system - if that's not windows (sorry), have to
adjust the include for winsock2.h

Best Regards & TIA,

Lars Uffmann

code (3 files, latter 2 are output from wxFormBuilder, stripped of
comments and merged GUI & event handler classes to one file):

********** BEGIN debugging.cpp ***********
#define __USE_W32_SOCKETS
#include <winsock2.h>

#define BUFLEN 5120
#define PORT 6000

#include <iostream>
using namespace std;
#include <sstream>
#include <boost/thread/thread.hpp>

#include "wx/wx.h"

#include "debuggingGUI.h"

debuggingGUImainFrame *mainWindow;
boost::thread *THREAD_FileReceiver;

/* *** */

void sendEndOfStream()
{
struct sockaddr_in saLocalhost;
SOCKET sEndOfStream;
int slen = sizeof(saLocalhost);
char buf[10];

sEndOfStream = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sEndOfStream == INVALID_SOCKET) {
cout << "Invalid socket, failed to create socket" << endl;
return;
}

memset((char *) &saLocalhost, 0, sizeof (saLocalhost));
saLocalhost.sin_family = AF_INET;
saLocalhost.sin_port = htons(PORT);
saLocalhost.sin_addr.s_addr = inet_addr ("127.0.0.1");

buf[0] = 0;
sendto(sEndOfStream, buf, 1, 0, (sockaddr *) &saLocalhost, slen);
closesocket (sEndOfStream);
}

int listenForAPacket() {
struct sockaddr_in si_me, si_other;
SOCKET s;
int slen = sizeof(si_other);
char buf[100];
int nRet;

s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (s == INVALID_SOCKET) {
cout << "Invalid socket, failed to create socket" << endl;
return -2;
}

memset((char *) &si_me, 0, sizeof (si_me));
si_me.sin_family = AF_INET;
si_me.sin_port = htons(PORT);
si_me.sin_addr.s_addr = htonl(INADDR_ANY);

nRet = bind(s, (sockaddr *) &si_me, sizeof (si_me));
if (nRet == SOCKET_ERROR) {
cout << "Failed to bind socket" << endl;
closesocket (s);
return -2;
}

cout << "mainWindow = " << (int) mainWindow << endl;
cout << mainWindow->txt1->GetValue() << endl;
recvfrom (s, &buf[0], 10, 0, (sockaddr *) &si_other, &slen);

cout << "mainWindow = " << (int) mainWindow << endl;
cout << mainWindow->txt1->GetName() << endl;

/* LOCKUP HERE */
cout << mainWindow->txt1->GetValue() << endl;

closesocket(s);
return 1;
}

/* *** */

debuggingGUImainFrame::debuggingGUImainFrame( wxWindow* parent )
:
mainFrame( parent )
{
}

void debuggingGUImainFrame::OnToggle( wxCommandEvent& event )
{
sendEndOfStream();
cout << "waiting for thread to end" << endl;
THREAD_FileReceiver->join();
cout << "thread finished" << endl;
}


/* *** */


class debuggingApp : public wxApp
{
virtual bool OnInit();
};

DECLARE_APP(debuggingApp)
IMPLEMENT_APP(debuggingApp)

bool debuggingApp::OnInit()
{
// Initialize WinSock2.2 DLL
// low-word = major, hi-word = minor
WSADATA wsaData = {0};
WORD wVer = MAKEWORD(2,2);

int nRet = WSAStartup (wVer, &wsaData);
if (nRet == SOCKET_ERROR) {
// WSAGetLastError()
cout << "Failed to init Winsock library" << endl;
return false;
}
mainWindow = new debuggingGUImainFrame((wxFrame *)NULL); //, -1,
_T("debugging"), wxPoint(50,50), wxSize(450,340) );

mainWindow->Show (TRUE);
SetTopWindow (mainWindow);
THREAD_FileReceiver = new boost::thread(&listenForAPacket);

return TRUE;
}
*********** END debugging.cpp ************

********** BEGIN debuggingGUI.h ***********
#ifndef __debuggingGUI__
#define __debuggingGUI__

#include <wx/string.h>
#include <wx/textctrl.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/button.h>
#include <wx/sizer.h>
#include <wx/frame.h>

class mainFrame : public wxFrame
{
private:

protected:
wxButton* cmd1;
// Virtual event handlers, overide them in your derived class
virtual void OnToggle( wxCommandEvent& event ){ event.Skip(); }

public:
wxTextCtrl* txt1;
mainFrame( wxWindow* parent, wxWindowID id = wxID_ANY, const
wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxSize( 500,300 ), long style =
wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL );

~mainFrame();
};

class debuggingGUImainFrame : public mainFrame
{
protected:
void OnToggle( wxCommandEvent& event );
public:
debuggingGUImainFrame( wxWindow* parent );
};

#endif //__debuggingGUI__
*********** END debuggingGUI.h ************

********** BEGIN debuggingGUI.cpp ***********
#include "debuggingGUI.h"

mainFrame::mainFrame( wxWindow* parent, wxWindowID id, const wxString&
title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame(
parent, id, title, pos, size, style )
{
this->SetSizeHints( wxDefaultSize, wxDefaultSize );

wxBoxSizer* sizerMain;
sizerMain = new wxBoxSizer( wxVERTICAL );

txt1 = new wxTextCtrl( this, wxID_ANY, wxT("1"), wxDefaultPosition,
wxDefaultSize, 0 );
sizerMain->Add( txt1, 0, wxALL, 5 );

cmd1 = new wxButton( this, wxID_ANY, wxT("toggle"),
wxDefaultPosition, wxDefaultSize, 0 );
sizerMain->Add( cmd1, 0, wxALL, 5 );

this->SetSizer( sizerMain );
this->Layout();

// Connect Events
cmd1->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(
mainFrame::OnToggle ), NULL, this );
}

mainFrame::~mainFrame()
{
// Disconnect Events
cmd1->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED,
wxCommandEventHandler( mainFrame::OnToggle ), NULL, this );
}
*********** END debuggingGUI.cpp ************
 
Reply With Quote
 
 
 
 
AnonMail2005@gmail.com
Guest
Posts: n/a
 
      02-19-2008
On Feb 19, 10:14*am, Lars Uffmann <(E-Mail Removed)> wrote:
> X-Post to comp.unix.programmer & comp.lang.c++
> F'Up set to comp.lang.c++
>
> Hi everyone!
>
> I am sorry that I am not able to reduce the bug-reproducing code
> further, I have been trying to debug this for 2 days at least. What I am
> doing is: I have a minimal wxWidgets application (GUI code as generated
> by wxFormBuilder at the bottom) with a frame mainFrane, a wxBoxSizer
> sizerMain, a wxTextCtrl txt1 and a wxButton cmd1. Now on wxApp::OnInit,
> I start a boost::thread that listens for a UDP datagram. The cmd1 button
> will send a simple UDP packet (just 1 byte, value 0) so the thread can
> finish, then call a join() on the thread to wait for it to exit.
>
> After that I want to access the properties of the wxTextCtrl txt1. In
> this case txt1->GetValue(). The very function worked fine just before
> the recvfrom call in my thread function. Right AFTER that call, when the
> UDP packet has been received, the program locks up IF I try to access
> txt1->GetValue(). txt1->GetName() works fine just in the line before. If
> I do not call this function, the application is fine and can be exited
> normally. If I do not call recvfrom, I can access txt1->GetValue() just
> fine.
>
> Now the really strange thing is: if I play back a "REAL" UDP packet,
> like the ones I am writing this application for, everything works just
> fine: the recvfrom gets called, gets (part of) the packet, and then the
> call to txt1->GetValue() yields the expected result, and the application
> is healthy.
>
> So does this mean that my usage of the socket function sendto(...) is
> wrong, and that it causes undefined behaviour to send a single byte with
> value 0 in a UDP datagram?
>
> Or if not - what could possibly be causing this lockup? Complete code
> following, sorry for the X-Post, but since it's a problem that occurs
> upon combined usage of the socket library & wxWidgets (and
> boost:thread), I think it makes sense to ask in both relevant groups.
> Unless of course its a winsock2 problem that would not occur with linux
> sockets...
>
> In the attached code, please search for the comment line that says
> * */* LOCKUP HERE */
>
> To compile this example you'll need wxwidgets, boost::thread and the
> sockets library for your system - if that's not windows (sorry), have to
> adjust the include for winsock2.h
>
> Best Regards & TIA,
>
> * * Lars Uffmann
>
> code (3 files, latter 2 are output from wxFormBuilder, stripped of
> comments and merged GUI & event handler classes to one file):
>
> ********** BEGIN debugging.cpp ***********
> #define __USE_W32_SOCKETS
> #include <winsock2.h>
>
> #define BUFLEN 5120
> #define PORT 6000
>
> #include <iostream>
> using namespace std;
> #include <sstream>
> #include <boost/thread/thread.hpp>
>
> #include "wx/wx.h"
>
> #include "debuggingGUI.h"
>
> debuggingGUImainFrame *mainWindow;
> boost::thread *THREAD_FileReceiver;
>
> /* *** */
>
> void sendEndOfStream()
> {
> * *struct sockaddr_in saLocalhost;
> * *SOCKET sEndOfStream;
> * *int slen = sizeof(saLocalhost);
> * *char buf[10];
>
> * *sEndOfStream = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
> * *if (sEndOfStream == INVALID_SOCKET) {
> * * *cout << "Invalid socket, failed to create socket" << endl;
> return;
> * *}
>
> * *memset((char *) &saLocalhost, 0, sizeof (saLocalhost));
> * *saLocalhost.sin_family = AF_INET;
> * *saLocalhost.sin_port = htons(PORT);
> * *saLocalhost.sin_addr.s_addr = inet_addr ("127.0.0.1");
>
> * *buf[0] = 0;
> * *sendto(sEndOfStream, buf, 1, 0, (sockaddr *) &saLocalhost, slen);
> * *closesocket (sEndOfStream);
>
> }
>
> int listenForAPacket() {
> * *struct sockaddr_in si_me, si_other;
> * *SOCKET s;
> * *int slen = sizeof(si_other);
> * *char buf[100];
> * *int nRet;
>
> * *s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
> * *if (s == INVALID_SOCKET) {
> * * *cout << "Invalid socket, failed to create socket" << endl;
> return -2;
> * *}
>
> * *memset((char *) &si_me, 0, sizeof (si_me));
> * *si_me.sin_family = AF_INET;
> * *si_me.sin_port = htons(PORT);
> * *si_me.sin_addr.s_addr = htonl(INADDR_ANY);
>
> * *nRet = bind(s, (sockaddr *) &si_me, sizeof (si_me));
> * *if (nRet == SOCKET_ERROR) {
> * * *cout << "Failed to bind socket" << endl;
> * * *closesocket (s);
> return -2;
> * *}
>
> * *cout << "mainWindow = " << (int) mainWindow << endl;
> * *cout << mainWindow->txt1->GetValue() << endl;
> * *recvfrom (s, &buf[0], 10, 0, (sockaddr *) &si_other, &slen);
>
> * *cout << "mainWindow = " << (int) mainWindow << endl;
> * *cout << mainWindow->txt1->GetName() << endl;
>
> * */* LOCKUP HERE */
> * *cout << mainWindow->txt1->GetValue() << endl;
>
> * *closesocket(s);
> * *return 1;
>
> }
>
> /* *** */
>
> debuggingGUImainFrame::debuggingGUImainFrame( wxWindow* parent )
> :
> mainFrame( parent )
> {
>
> }
>
> void debuggingGUImainFrame::OnToggle( wxCommandEvent& event )
> {
> * *sendEndOfStream();
> cout << "waiting for thread to end" << endl;
> * *THREAD_FileReceiver->join();
> cout << "thread finished" << endl;
>
> }
>
> /* *** */
>
> class debuggingApp : public wxApp
> {
> * *virtual bool OnInit();
>
> };
>
> DECLARE_APP(debuggingApp)
> IMPLEMENT_APP(debuggingApp)
>
> bool debuggingApp::OnInit()
> {
> * *// Initialize WinSock2.2 DLL
> * *// low-word = major, hi-word = minor
> * *WSADATA wsaData = {0};
> * *WORD wVer = MAKEWORD(2,2);
>
> * *int nRet = WSAStartup (wVer, &wsaData);
> * *if (nRet == SOCKET_ERROR) {
> * * *// WSAGetLastError()
> * * *cout << "Failed to init Winsock library" << endl;
> return false;
> * *}
> * *mainWindow = new debuggingGUImainFrame((wxFrame *)NULL); //, -1,
> _T("debugging"), wxPoint(50,50), wxSize(450,340) );
>
> * *mainWindow->Show (TRUE);
> * *SetTopWindow (mainWindow);
> * *THREAD_FileReceiver = new boost::thread(&listenForAPacket);
>
> * *return TRUE;}
>
> *********** END debugging.cpp ************
>
> ********** BEGIN debuggingGUI.h ***********
> #ifndef __debuggingGUI__
> #define __debuggingGUI__
>
> #include <wx/string.h>
> #include <wx/textctrl.h>
> #include <wx/gdicmn.h>
> #include <wx/font.h>
> #include <wx/colour.h>
> #include <wx/settings.h>
> #include <wx/button.h>
> #include <wx/sizer.h>
> #include <wx/frame.h>
>
> class mainFrame : public wxFrame
> {
> * *private:
>
> * *protected:
> * * *wxButton* cmd1;
> * * *// Virtual event handlers, overide them in your derived class
> * * *virtual void OnToggle( wxCommandEvent& event ){ event.Skip(); }
>
> * *public:
> * * *wxTextCtrl* txt1;
> * * *mainFrame( wxWindow* parent, wxWindowID id = wxID_ANY, const
> wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition,
> const wxSize& size = wxSize( 500,300 ), long style =
> wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL );
>
> * * *~mainFrame();
>
> };
>
> class debuggingGUImainFrame : public mainFrame
> {
> protected:
> * * * * void OnToggle( wxCommandEvent& event );
> public:
> * * * * debuggingGUImainFrame( wxWindow* parent );
>
> };
>
> #endif //__debuggingGUI__
> *********** END debuggingGUI.h ************
>
> ********** BEGIN debuggingGUI.cpp ***********
> #include "debuggingGUI.h"
>
> mainFrame::mainFrame( wxWindow* parent, wxWindowID id, const wxString&
> title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame(
> parent, id, title, pos, size, style )
> {
> * *this->SetSizeHints( wxDefaultSize, wxDefaultSize );
>
> * *wxBoxSizer* sizerMain;
> * *sizerMain = new wxBoxSizer( wxVERTICAL );
>
> * *txt1 = new wxTextCtrl( this, wxID_ANY, wxT("1"), wxDefaultPosition,
> wxDefaultSize, 0 );
> * *sizerMain->Add( txt1, 0, wxALL, 5 );
>
> * *cmd1 = new wxButton( this, wxID_ANY, wxT("toggle"),
> wxDefaultPosition, wxDefaultSize, 0 );
> * *sizerMain->Add( cmd1, 0, wxALL, 5 );
>
> * *this->SetSizer( sizerMain );
> * *this->Layout();
>
> * *// Connect Events
> * *cmd1->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(
> mainFrame::OnToggle ), NULL, this );
>
> }
>
> mainFrame::~mainFrame()
> {
> * *// Disconnect Events
> * *cmd1->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED,
> wxCommandEventHandler( mainFrame::OnToggle ), NULL, this );}
>
> *********** END debuggingGUI.cpp ************


wxWidgets and sockets are OT in this newsgroup.
 
Reply With Quote
 
 
 
 
Lars Uffmann
Guest
Posts: n/a
 
      02-19-2008
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> wxWidgets and sockets are OT in this newsgroup.


That is a matter of perspective, especially when the bug is somewhere in
between and might also involve boost::thread usage.

However, a fullquote followed by a single line of a useless "smart"
remark is always OT.

....

Lars
 
Reply With Quote
 
AnonMail2005@gmail.com
Guest
Posts: n/a
 
      02-19-2008
On Feb 19, 10:44*am, Lars Uffmann <(E-Mail Removed)> wrote:
> (E-Mail Removed) wrote:
> > wxWidgets and sockets are OT in this newsgroup.

>
> That is a matter of perspective, especially when the bug is somewhere in
> between and might also involve boost::thread usage.
>
> However, a fullquote followed by a single line of a useless "smart"
> remark is always OT.
>
> ...
>
> * *Lars


My news reader does the quoting for me automagically. But don't
worry, you will get used to it.
 
Reply With Quote
 
red floyd
Guest
Posts: n/a
 
      02-19-2008
(E-Mail Removed) wrote:
> On Feb 19, 10:44 am, Lars Uffmann <(E-Mail Removed)> wrote:
>> (E-Mail Removed) wrote:

[redacted]
>>
>> However, a fullquote followed by a single line of a useless "smart"
>> remark is always OT.
>>
>> ...
>>
>> Lars

>
> My news reader does the quoting for me automagically. But don't
> worry, you will get used to it.


Wrong. *YOU* will get used to the etiquette of this newsgroup.

http://www.parashift.com/c++-faq-lit...t.html#faq-5.4

And, great, your newsreader quotes the whole post. So what, so does
mine. I edit it before posting. You can do the same.
 
Reply With Quote
 
David Schwartz
Guest
Posts: n/a
 
      02-20-2008
On Feb 19, 7:14 am, Lars Uffmann <(E-Mail Removed)> wrote:

> I am sorry that I am not able to reduce the bug-reproducing code
> further, I have been trying to debug this for 2 days at least. What I am
> doing is: I have a minimal wxWidgets application (GUI code as generated
> by wxFormBuilder at the bottom) with a frame mainFrane, a wxBoxSizer
> sizerMain, a wxTextCtrl txt1 and a wxButton cmd1. Now on wxApp::OnInit,
> I start a boost::thread that listens for a UDP datagram. The cmd1 button
> will send a simple UDP packet (just 1 byte, value 0) so the thread can
> finish, then call a join() on the thread to wait for it to exit.


UDP is unreliable. If the datagram is dropped/lost, the thread will
not exit. Some platforms do offer reliable local UDP, but the platform
you are using may not.

> After that I want to access the properties of the wxTextCtrl txt1. In
> this case txt1->GetValue(). The very function worked fine just before
> the recvfrom call in my thread function. Right AFTER that call, when the
> UDP packet has been received, the program locks up IF I try to access
> txt1->GetValue(). txt1->GetName() works fine just in the line before. If
> I do not call this function, the application is fine and can be exited
> normally. If I do not call recvfrom, I can access txt1->GetValue() just
> fine.


Perhaps the thread that sends the datagram does something to 'txtl'?

> Now the really strange thing is: if I play back a "REAL" UDP packet,
> like the ones I am writing this application for, everything works just
> fine: the recvfrom gets called, gets (part of) the packet, and then the
> call to txt1->GetValue() yields the expected result, and the application
> is healthy.


That definitely sounds like the problem is something else the thread
that sends the UDP datagram does.

[snip]

I think your problem is this:

1) Call the thread that sends the datagram thread A. It sends the
datagram and then blocks waiting for thread B to terminate. This
thread is operating from the frame, so it holds a lock on the frame.

2) Thread B gets the datagram and tries to access 'txtl'. The problem
is that thread A holds a lock on the frame. So thread B must wait
until thread A releases the lock.

At this point, thread A is waiting for thread B to finish, but thread
B cannot finish until it gets the frame lock, but thread A holds the
frame lock.

DS
 
Reply With Quote
 
Lars Uffmann
Guest
Posts: n/a
 
      02-20-2008
Hi David,

David Schwartz wrote:
> UDP is unreliable. If the datagram is dropped/lost, the thread will
> not exit. Some platforms do offer reliable local UDP, but the platform
> you are using may not.


The datagram is definitely arriving, my code is doing a cout to verify
it has reached the step after recvfrom

> Perhaps the thread that sends the datagram does something to 'txtl'?

Well - the _thread_ sending the datagram is the main wxWindows thread
(event handler), but the function sending the datagram isn't doing
anything to txt1.

> I think your problem is this:
> [...]
> At this point, thread A is waiting for thread B to finish, but thread
> B cannot finish until it gets the frame lock, but thread A holds the
> frame lock.


Wow. Very nice analysis. This might indeed be the problem here. It
definitely gave me a new insight into the situation. And it would
explain the difference between receiving a "selfmade" UDP packet
(because only then thread A is waiting for thread B) and the played back
packets.

Thank you very much, I think I'll be able to work around this now (got
pointed to custom events in wxwindows newsgroup).

Best Regards,

Lars
 
Reply With Quote
 
Lars Uffmann
Guest
Posts: n/a
 
      02-21-2008
David,

David Schwartz wrote:
> I think your problem is this:
>
> 1) Call the thread that sends the datagram thread A. It sends the
> datagram and then blocks waiting for thread B to terminate. This
> thread is operating from the frame, so it holds a lock on the frame.
>
> 2) Thread B gets the datagram and tries to access 'txtl'. The problem
> is that thread A holds a lock on the frame. So thread B must wait
> until thread A releases the lock.
>
> At this point, thread A is waiting for thread B to finish, but thread
> B cannot finish until it gets the frame lock, but thread A holds the
> frame lock.



After some further testing, I have pinpointed the problem, and it was
exactly what you said. The following (reduced) example proves that the
whole thing isn't even related to the socket library, but solely happens
to do the mentioned frame lock. Thanks a lot! Now I need to find a way
around this

Best Regards,

Lars

*** code from here ***
#include <iostream>
using namespace std;
#include <boost/thread/thread.hpp>

#include "wx/wx.h"
#include <wx/string.h>
#include <wx/textctrl.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/button.h>
#include <wx/sizer.h>
#include <wx/frame.h>

class mainFrame : public wxFrame
{
protected:
// Virtual event handlers, overide them in your derived class
virtual void OnToggle( wxCommandEvent& event ){ event.Skip(); }

public:
wxButton* cmd1;
wxTextCtrl* txt1;
mainFrame( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString&
title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const
wxSize& size = wxSize( 500,300 ), long style =
wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL );
~mainFrame();
};

class debuggingGUImainFrame : public mainFrame
{
protected:
void OnToggle( wxCommandEvent& event );

public:
debuggingGUImainFrame( wxWindow* parent );
};


mainFrame::mainFrame( wxWindow* parent, wxWindowID id, const wxString&
title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame(
parent, id, title, pos, size, style )
{
this->SetSizeHints( wxDefaultSize, wxDefaultSize );

wxBoxSizer* sizerMain;
sizerMain = new wxBoxSizer( wxVERTICAL );

txt1 = new wxTextCtrl( this, wxID_ANY, wxT("1"), wxDefaultPosition,
wxDefaultSize, 0 );
sizerMain->Add( txt1, 0, wxALL, 5 );

cmd1 = new wxButton( this, wxID_ANY, wxT("toggle"), wxDefaultPosition,
wxDefaultSize, 0 );
sizerMain->Add( cmd1, 0, wxALL, 5 );

this->SetSizer( sizerMain );
this->Layout();

// Connect Events
cmd1->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(
mainFrame::OnToggle ), NULL, this );
}

mainFrame::~mainFrame()
{
// Disconnect Events
cmd1->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(
mainFrame::OnToggle ), NULL, this );
}

/* *** */

debuggingGUImainFrame *mainWindow;
boost::thread *myThread;

/* *** */

void demonstrateFrameLock()
{
sleep (1);
cout << "child thread: taking a nap (2 seconds)" << endl;
sleep (2);
cout << "child thread: woke up!" << endl;

cout << "child thread: mainWindow->txt1->GetValue = " <<
mainWindow->txt1->GetValue() << endl;
cout << "child thread: thread finished" << endl;
}

/* *** */

debuggingGUImainFrame::debuggingGUImainFrame( wxWindow* parent )
:
mainFrame( parent )
{
}

void debuggingGUImainFrame::OnToggle( wxCommandEvent& event )
{
myThread = new boost::thread(&demonstrateFrameLock);
cout << "main thread: sleeping 5 seconds" << endl;
sleep (5);
cout << "main thread: done sleeping" << endl;

// cout << "main thread: waiting for child thread to end" << endl;
// myThread->join();

delete myThread;
myThread = 0;

cout << "main thread: thread finished" << endl;
}

/* *** */


class debuggingApp : public wxApp
{
virtual bool OnInit();
};

DECLARE_APP(debuggingApp)
IMPLEMENT_APP(debuggingApp)

bool debuggingApp::OnInit()
{
mainWindow = new debuggingGUImainFrame((wxFrame *)NULL); //, -1,
_T("debugging"), wxPoint(50,50), wxSize(450,340) );

mainWindow->Show (TRUE);
SetTopWindow (mainWindow);

return TRUE;
}
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
stange problem with bind() funcktion - winsock2 s_4@wp.pl C Programming 6 02-17-2007 11:43 PM
WinSock2 corruption, DUN Connection Failures, no IPv6 on WinXP SP2 =?Utf-8?B?SmVkYV9XYXJyaW9yNw==?= Wireless Networking 3 09-06-2006 09:52 PM
Dealing with dead sockets on a winsock2 sever Holger Fleckenstein C++ 8 06-28-2005 09:38 PM
Clear hangs up - & hangs up - & hangs up Sue Bilstein NZ Computing 26 03-07-2004 01:33 AM
Winsock2.2.exe error message on bootup. Arawak Computer Support 1 12-22-2003 02:42 AM



Advertisments