Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Thread problem

Status
Not open for further replies.

BlairFonville

Technical User
Feb 25, 2003
3
0
0
US
I have a great problem. I need to have two my program reading two serial ports at the same time. So the clear solution to to have three threads. 1 for com1, 1 for com2, and 1 for the main program. If I run my program and set it up to read only com1 the program reads the serial device beautifully (it is a GPS). If I then run my program and set it up to read only com2 the program reads the com2 device perfectly. The problem occurs only when I setup both ports and try to have the program read both at the same time.

I didn't expect to have any problems since I am instantiating each port seperately. I have verified that I get to the thread class (which I call CCommThread) twice, one time for each port. CCommControl is the class that I use to give each device its own instantiation. I setup the ports here, establish a port handle, and create and terminate the thread for the port. Here is what I am doing...

// My document class
class CPRGPSComDoc : public CDocument
{ ...
CCommControl m_ccGPSPort; //GPS CommControl
CCommControl m_ccTNCPort; //TNC CommControl
}

// My com port control class
------------------------------------------------
class CCommControl // HEADER
{ ...
CCommThread* m_pThread;
}

// Here is where I setup the ports' handles
LONG CCommControl::SetPortHandle(CString port)
{
lpszDevice = port;
m_lLastError = ERROR_SUCCESS; //Reset error state
m_hCommPort = CreateFile(lpszDevice,
GENERIC_READ | GENERIC_WRITE,
0, // exclusive access
NULL, // no security
OPEN_EXISTING,
0, // no overlapped I/O
NULL); // null template
if (m_hCommPort == INVALID_HANDLE_VALUE)
{
m_hCommPort = 0; // Reset file handle
m_lLastError = ::GetLastError();
return m_lLastError;
}
return m_lLastError;
}

And this is where I "poll" the GPS or the TNC. Both devices have their own CCommControl instantiation (as shown above in the document class header)

void CCommControl::pollData()
{
//Create new (suspended) UI thread
m_pThread = (CCommThread*)AfxBeginThread(RUNTIME_CLASS CCommThread),
THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);

//Initialize CCommThread member variables
m_pThread->m_hCommHandle = m_hCommPort;
m_pThread->m_bSelectPollMethod = m_bselectPollMethod;
m_pThread->m_GPSSentenceType = m_GPSSentenceType;
m_pThread->m_pView = m_pView; //Give it view class access

//Create a duplicate handle of the thread.
//This is so I can WM_QUIT the thread and still have
//access to its status after MFC autodeletes it. This
//allows me to have verification that it has terminated.
//Reference Programming Windows With MFC (p.994)
BOOL ret = DuplicateHandle(GetCurrentProcess(),
m_pThread->m_hThread,
GetCurrentProcess(), &m_dupThreadHandle, 0, FALSE,
DUPLICATE_SAME_ACCESS);

//Resume thread Operations
DWORD ResumeReturn = m_pThread->ResumeThread();
}


Now, this all seems to work fine (especially because it works perfectly when I only poll a single port- instead of both ports at the same time). I believe that I have narrowed the problem to within the CCommThread class
(given below)

void CCommThread::ReadPort()
{
do
{
ReceivedChar = WaitCommEvent (m_hCommHandle,&commevent,NULL);
if (ReceivedChar)
::ReadFile(m_hCommHandle, &sBuffer, 1,
&iBytesRead, NULL);
...
}

This is a short clip of the readport function. But I have determined that the program stops responding at this point. I believe it has a problem with the WaitCommEvent function.

I know that this is a long post, and I appologize. But, I am really confused at this point. I can't figure out why it isn't working. Could it have anything to do with the overlapped I/O? I don't understand what overlapped
is.

Anyway, Thanks for reading. I would really appreciate some help here.
Thanks, Blair

PS. I have a feeling that the formatting of this post will be messed up. If so, sorry about that
 
Hi,

Could it be you are using CreateFile with exclusive access. I know they are different ports, but maybe.

Overlapping allows multiple reads on an object whilst it is open.

(Specal options can be set in the CreateFile arguments to specify special actions such as automatic file deletion after the file is closes. You can also specify such things as a sequential scan of the file for reading. The operating system can then optimized the allocation of resources for the opened file. One of the most useful techniques in using file operations is Overlapped I/O. Usually when ReadFile and WriteFile are called, they block until either I/O is complete or there is an error generated. In Overlapped I/O, these functions return without blocking, and I/O occurs in the background. The calling process can either be signaled or can perform polling to test for I/O completion.

and maybe :

good luck.

Rich.
 
Rich, thanks for the reply. Actually, last night I brought some of the equipment home from the office to continue my work at home. When I hooked the devices into my home computer, everything worked! So I went back to the office an noticed that I was using one serial port from the motherboard and one serial port from an ISA card (instead of both from the motherboard as I had at home). So when I, instead, hooked both devices to motherboard serial ports my software worked at the office as well. I don't know why it has problems with a motherboard/ISA card port combo and not motherboard/motherboard, but whatever.

Actually, I truely don't understand why it would matter. Especially since the read operations are in two different threads and the processor should only work either to get info from the motherboard serial port OR the ISA card serial port at any given time. But, I'm not going to loose any more sleep (or hair) on this one!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top