|
The point is that the class wizard creates the code when adding a class with a base class of CWinThread() and that the code the thread executes should be in the UIThread::Run() function. If my thread execution is not performed by Run() then where do I put my thread code? This really shouldn't be this difficult. All I want is to click a button to start the test and click another button to abort the test.
|
|
|
|
|
Right. Kind of a catch-22 deal - you can't create a window without running the threads message
loop and you can't run the message loop before creating the window
If you insist on a separate thread for just the modal dialog then start the UI thread - run it,
and post a thread message to it. Respond to the thread message and then call DoModal() on the
dialog.
That's still way more complicated than it needs to be.
|
|
|
|
|
Very much a catch 22. Let me say that I am NOT a Windows programmer. How would you set it up? My tab page has a button that invokes OnButtonBeginTest() that executes the test code (that could take an hour). While the test is running I can't click on any other buttons on my tab page. If I could then I would add an abort test button to the tab page.
|
|
|
|
|
BuckBrown wrote: Let me say that I am NOT a Windows programmer
Too late - you're a windows programmer.
I prefer 1 UI thread (the CWinApp one in MFC).
So, I would
1) respond to the button click
2) create/show a modeless progress dialog
3) disable the main window if appropriate or at least the button so the user can't click it again
4) start a worker thread which executes the test code
4a)The worker thread could periodically post messages to the modeless dialog to indicate progress
(if that info is available) - this could be done via class method as well but then you may have
to handle thread synchronization.
5) If the user clicks cancel (if provided in the modeless dialog) then somehow inform the thread
to terminate - using a flag variable or event object.
6) If the test thread ends normally then it could post a message to the main window or the dialog
(whichever is appropriate) indicating completion.
7) on receipt of the completion message, destroy/cleanup the thread object, the modeless dialog,
and reanable any disabled windows from step 3
Something like that.
Mark
|
|
|
|
|
Thanks, I'll try this approach tomorrow. Something's gotta give. I've been trying to do this since Monday morning - 32 hours to not yet do what an experienced Windows guy could do in 32 minutes!
|
|
|
|
|
Also, the following code (where I was spawing the UI thread) greys out the area on my tab page where the modeless dialog should appear but the modeless box does not appear until the AfxMessageBox() command.
pInProgress->Create(IDD_DIALOG_PROGRESS, this);
pInProgress->CenterWindow();
pInProgress->SetForegroundWindow();
pInProgress->UpdateData(TRUE);
pInProgress->UpdateWindow();
pInProgress->ShowWindow(SW_SHOW);
Sleep(5000);
AfxMessageBox("Wait");
// theApp.m_pThread = AfxBeginThread(RUNTIME_CLASS(UIThread), 0, THREAD_PRIORITY_NORMAL);
Isn't there a way to flush the messages? Or at least FORCE this window to display?
Everthing I do in Windows needs some information that I dont have access to!
|
|
|
|
|
The messages won't flush until the thread flushing the messages runs
The Sleep() is preventing that.
|
|
|
|
|
What happens if you move the "pInProgress->UpdateWindow();" below the ShowWindow() call?
|
|
|
|
|
|
If you can break up the work done in the spawned thread into separate subtasks, you could use this[^] progress dialog class.
/ravi
|
|
|
|
|
I need to discover the presence of a Bluetooth device (and communicate with it via a virtual serial port). Device discover is an easy task using Microsoft's Bluetooth API - it works very well indeed!
However, Microsoft's API does not appear to be compatible with a large number of bluetooth adaptors out there (primarily Widcomm, but also BlueSolei, Toshiba, etc). So on these adaptors, my application is likely to bomb I understand this is also a problem pre XP SP2.
So, does any one know of an SDK (for C++ use) which provides a simple universal unified API (or wrapper) for the various Bluetooth implementations out there (or at least the main two)?
You would have thought the developers of Bluetooth could have sat at a table and agreed some basic common API for the software side of things like they did with the hardware side, but apparently not!
Much appreciated
--
The Obliterator
|
|
|
|
|
Obliterator wrote: You would have thought the developers of Bluetooth could have sat at a table and agreed some basic common API for the software side of things like they did with the hardware side, but apparently not!
Bluetooth 'developpers' as you call them didn't work at all on a hardware part. They only developped a specification that defines how different devices can communicate together, the different layers of the BT stack, the different profiles, ... The software API that you are looking for is way outside the scope of the Bluetooth specifications (a lot of devices won't even need to be 'managed' by a operating system).
I never worked with the Microsoft's Bluetooth API so I cannot really help you on that part. As far as I know (but I'm not sure at all), this API is for embedded development only, no ?
Anyway what you can still do is use a BT module that you can connect to your serial port and send AT commands to do some specific actions (like starting an inquiry, connect to a specific Bluetooth device, ...). Of course, this will require that you parse the commands yourself.
|
|
|
|
|
You're right, the Bluetooth syndicate did only produce the specification. I just wish they'd produced a spec for the software API's as well! I think its what has really held back the popularity and take-up of Bluetooth. There are just so many software related problems, many of which wouldn't arisen with a common sw specification.
Microsoft's API is a step in the right direction. They're trying to harmonize all the various drivers out there. Its definitely usable in Windows BTW (but only Win XP SP2) - I'm using it very reliably now. The only problem is it doesn't encompass one of the largest manufacturers of Bluetooth adaptors in the market place (Widcomm).
I have no control over which BT adaptopr is used - its the user's decision - it may be built into their laptop for example. But I need to talk to it whether its compatible with MS API or not.
All I want to do is automatically detect my device, pair it (authenticate it) and enable the virtual serial port. I then look up which port number got assigned to the device and communicate with my device via standard serial port communication. I want to do all this without any user interaction (otherwise they might as well pair the device themselves). My implementation works perfectly with Microsoft's API (plus some registry querying to determine the com port value).
The problem is it looks like I'll need to do the same for Widcomm's API, BlueSolei's, Toshiba's, etc. I was rather hoping somebody might have done this work already for me!
Thanks anyhow
--
The Obliterator
|
|
|
|
|
I am developing Socket application that is going to send packet across network. The data packets contain, STX, Lenght, Opcode, Type, Qualifier, Data[128], CRC, ETX. I was hoping to be able to send the packet via send command. However, I might run into a problem where the que is full and only half my packet goes out. This would cause a sync problem. Is there any way, i can verify how much space is available in the outgoing write buffer.
if( TxQueue.Pop( &temp_packet ) == true )
{
iResults = send( client_socket, (char *)&temp_packet, sizeof(temp_packet), NULL );
if( iResults != sizeof(temp_packet) )
Error = -1;
}
Scott Dolan
Jernie Corporation
Engineering & Manufacturing
Software, Hardware, & Enclosures
|
|
|
|
|
ScotDolan wrote: Is there any way, i can verify how much space is available in the outgoing write buffer
Not that I know of.
It looks like your data is already queued for sending which is good IMO.
I'm assuming you are using non-blocking socket (or it wouldn't be an issue).
Maybe changing the send logic a bit will help...
if( TxQueue.Pop( &temp_packet ) == true )
{
BYTE *pCurSendByte = (BYTE *)&temp_packet;
int iBytesRemaining = sizeof(temp_packet);
while (iBytesRemaining > 0)
{
iResults = send( client_socket, (char *)pCurSendByte, iBytesRemaining, NULL );
if( iResults != SOCKET_ERROR )
{
iBytesRemaining -= iResults;
if (iBytesRemaining > 0)
{
pCurSendByte += iResults;
}
}
else
{
int nWSAErrorCode = WSAGetLastError();
if (nWSAErrorCode != WSAEWOULDBLOCK)
{
Error = -1;
break;
}
}
}
}
This is fairly ok on a separate thread but more efficient would be to use an event object with
WSAEventSelect() to wait on FD_WRITE whenever send() doesn't write all the bytes (or returns
WSAEWOULDBLOCK error) in one shot.
Takes a few extra lines of code
-- modified at 16:37 Thursday 8th February, 2007
*EDIT* Added WSAEWOULDBLOCK error handling
|
|
|
|
|
Also, if using TCP, it's important to receive data efficiently on the other end. send() depends
on the receiving end having buffer room as well!
|
|
|
|
|
Mark,
That code basiclly makes the send function into a blocking function.
I am try to develop a real-time socket applciation(As best as possible). Right now, the send and recv are in a single worker thread. The worker thread also maintains the status of the connection. If disconnects occures, thread will automaticlly reattempt to connect and update status byte within the class notifying calling function the socket is disconnected.
The Blocking function does not work in my application because, i will be waiting on write, when i could receiving data.
This all said, I thinking I might have to create two or three worker threads within this socket class I am developing.
One thread to recv packet and place in the safeque.
One Thread to send packet from safeque.
One Thread to check for FD_CLOSE and FD_CONNECTION events.
Do you think the three thread class would work.
Scott Dolan
Jernie Corporation
Engineering & Manufacturing
Software, Hardware, & Enclosures
|
|
|
|
|
ScotDolan wrote: This all said, I thinking I might have to create two or three worker threads within this socket class I am developing.
One thread to recv packet and place in the safeque.
One Thread to send packet from safeque.
One Thread to check for FD_CLOSE and FD_CONNECTION events.
That works but for even more throughput with minimal threads - one thread for sends and recvs,
one for queueing data for send, and one for handling queued received data works well.
The problem with multiple threads sending and receiving is that it's not guaranteed to be safe
on the same socket. You end up blocking to wait for the other anyway so having more than one
thread for recv and send is IMO unnecessary.
In my socket I/O thread loops, I have an array of events - 1 for termination, 1 for queued send
data, and one for FD_READ/FD_CLOSE events from the socket. Using WaitForMultipleObjects() I wait
on those events (outer loop). When an event is signalled check for terminate (exiting the thread
if signalled), check if FD_READ and if so loop until WSAWOULDBLOCK error, if queued send data
then send like my sample code. After a send check for more queued send packets and set the event
if necessary so next loop will catch it immediately. It works well for real time streaming
data.
|
|
|
|
|
I think i understand you. You basicly wait for events Once you get a read event you start a thread to handle that event and read the fifo. But, before you start that thread you make sure the past current read thead has terminate.
I like the sounds of this socket. Do you have it posted up here. Send me a copy. Please....
Right now, I am going to try simpler versiion of that, I am going to do all my reads and write in the same thread. It will attempt to write one packet, than read one packet and it will never block.. But, I am betting this will not working my application. My new code below.. Let
<br />
case LOOP_CLIENT:<br />
WSAEnumNetworkEvents(client_socket, g_hClientEvent, &NetworkClientEvents);<br />
if( NetworkClientEvents.lNetworkEvents == FD_CLOSE)<br />
{ <br />
printf("Client Socket Closed Message: \n\r"); <br />
WSACloseEvent(g_hClientEvent);<br />
closesocket(client_socket);<br />
WSACleanup();<br />
state = CONNECT_CLIENT;<br />
}<br />
<br />
if( NetworkClientEvents.lNetworkEvents == FD_CONNECT)<br />
{<br />
if (0 != NetworkClientEvents.iErrorCode[FD_CONNECT_BIT]) {<br />
printf("Client Connection Failed: \n\r"); <br />
state = CONNECT_CLIENT;<br />
}else{ <br />
printf("Client Connected Message: \n\r");<br />
state = LOOP_CLIENT;<br />
}<br />
}<br />
<br />
<br />
<br />
if( txbytesremaining == 0 )<br />
{<br />
if( TxQueue.Pop( &temp_txpacket) == true)<br />
{ <br />
temp_txbuffer = (char *)&temp_txpacket; <br />
int txbytesremaining = sizeof(temp_txbuffer); <br />
iResults = send( client_socket, (char *)temp_txbuffer, txbytesremaining, NULL ); <br />
if( iResults != SOCKET_ERROR ) <br />
{ <br />
txbytesremaining -= iResults;<br />
if (txbytesremaining > 0) <br />
temp_txbuffer += iResults;
}else{ <br />
break; <br />
} <br />
}<br />
}else{<br />
iResults = send( client_socket, (char *)temp_txbuffer, txbytesremaining, NULL ); <br />
if( iResults != SOCKET_ERROR ) <br />
{ <br />
txbytesremaining -= iResults;<br />
if (txbytesremaining > 0)<br />
temp_txbuffer += iResults;
}else{<br />
break;
}<br />
}<br />
<br />
<br />
<br />
if( rxbytesremaining == 0 )<br />
rxbytesremaining = sizeof(temp_rxbuffer);<br />
<br />
iResults = recv( client_socket, (char *)temp_rxbuffer, rxbytesremaining, NULL ); <br />
switch( iResults )<br />
{<br />
case 0:<br />
break;<br />
case SOCKET_ERROR:<br />
break;<br />
default:<br />
rxbytesremaining -= iResults;<br />
temp_rxbuffer += iResults; <br />
if( rxbytesremaining == 0 )<br />
{<br />
temp_rxpacket = (INDEPENDENCER_PKT *)temp_rxbuffer;
if( temp_rxpacket.verifyCRC() )<br />
{<br />
m_TcpClientRxPktCount++;<br />
RxQueue.Push( temp_rxpacket );<br />
}else{<br />
m_TcpClientRxPktCrcErrCount++;<br />
}<br />
}<br />
break;<br />
}
<br />
break;
Scott Dolan
Jernie Corporation
Engineering & Manufacturing
Software, Hardware, & Enclosures
|
|
|
|
|
ScotDolan wrote: You basicly wait for events Once you get a read event you start a thread to handle that event and read the fifo. But, before you start that thread you make sure the past current read thead has terminate.
No actually I'm talking about waiting on events when already in the send/recv thread.
For good throughput using TCP it's important to keep the socket send buffers full and the recv
buffers empty. The socket should never have to wait for the app to receive data from its
buffers otherwise communication stops. Of course, when there's no data to send that's fine -
that means everything's caught up. Using the method below, the thread deals solely with
sending and receiving on the socket. Data to send is queued by another thread, which sets
the datatosendevent. Received data is immediately queued and an event is set indicating to
another thread that data has been received for processing. Those other threads can take as much
time processing as they want - the point is the send/recv thread keeps the data flowing with
minimal waiting. Also, being completely event driven, there's little wasted CPU cycles.
while (1)
{
WaitMultipleObjects() on terminateevent, datatosendevent, socketevent(FD_READ/FD_CLOSE)
if (terminateevent)
break;
if (socketevent)
{
if (FD_CLOSE event)
{
notify app that remote socket closed
break;
}
else
{
loop calling recv() (queueing complete packets)
until WSAWOULDBLOCK error
Notify recv handler thread using an event object when received data available
}
}
if (datatosendevent)
{
dequeue a send packet
loop calling send()
until WSAWOULDBLOCK error or no more queued send data
if WSAWOULDBLOCK and still data on send queue then set datatosendevent
}
}
return (exit thread)
|
|
|
|
|
Assuming it's TCP, why not just resend whatever send() couldn't send? send() returns the number of bytes it managed to send...
--
Verletzen zerfetzen zersetzen zerstören
Doch es darf nicht mir gehören
Ich muss zerstören
|
|
|
|
|
If you want to use TCP, then you must write your code to accommodate partial sends and recvs, and also to accommodate multiple sends and recvs. There is no way around this. TCP is reliable but it's stream-based, not message-based. This means that TCP views the data as a simple stream of singular bytes, and it's up to the appication to decide what the bytes mean. Even if you could somehow check for availability of room in the send buffer, that information is completely unrelated to how the stack will ultimately send data out over the wire, and of course is totally unrelated to how the recipient stack will re-assemble data at the receiving side.
UDP, on the other hand, is message-based. It will definitely preserve "messages" or "packets". However, unlike TCP, UDP is unreliable, in the sense that either the entire message will be delivered, or nothing at all will be delivered.
You need to decide on your requirements.
Mike
|
|
|
|
|
Mike,
From my understanding, all the UDP data grams are recieved into a single recieve FIFO. There is no way within winsock to pull packets out of the buffers. And even if you could pull packets out of buffer, there is no garantee that all the packets are of the same size as application/someone might placed a unexpected packet..
Scott Dolan
Jernie Corporation
Engineering & Manufacturing
Software, Hardware, & Enclosures
|
|
|
|
|
So I am writing a mixed assembly, part of it is managed C++ and part of it is unmanaged. In unmanaged part I'm calling function atan2f( y,x) from <math.h> . it runs in double for loop over whole matrix and takes a very long time to compute. In fact, when I change this code from unmanaged to managed and instead of atan2f call System::Math::Atan2(y,x), I get significant speed gains. Difference is so obvious that I cant process images in real time with atan2f, whilst with Math::Atan2 I can. How is that possible?
Is there any other(faster) way to compute atan2 in unamanaged C++ code?
|
|
|
|
|
The managed version becomes native code as soon as it's run for the first time. Perhaps it's written more efficiently ?
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
|
|
|
|
|