-
To Hunter2,
Yes, I've checked the thread creation and I get valid values similar too other PortThreads that work fine.
PortThread[3] doesn't change between the constructor to Activate_Crypto_Thread the first time. Curiously, upon calling Activate_Crypto_Thread the second or third times, it inexplicably changes. In fact it almost seems to corrupt itself getting values that simply don't make sense. I've checked the whole solution for other redefinitions but to no avail.
The EventHandles are initialized properly, and are unchanged at the call of Send_Crypto_Key_1, however the code'll crash at the declaration of aword so I can't say for sure whether they stay like that.
To Salem,
Port does have the same scope as the threads.
Unfortunately I'm very new to threads and don't know how to take into account the thread API not returing a proper 'this' pointer to a C++ class member function.
Code, by in large, has remained unchanged with respect to this particular problem, however, here's the entirety of the Activate_Crypto_Key function as that seems to be where it's messing up (with the PortThread redefining itself).
Code:
bool C_Control::Activate_Crypto_Port(int PortNumber, bool ActiveYN)
{
// this function starts or suspends a port thread depending
// on the state of ActiveYN and opens the log files the first
// time a port is activated
static int Times_Through[4] = {0,0,0,0};
DWORD SuspendCount;
// PortThread[3]= AfxBeginThread(StartCryptoPortThread, &Port[3],THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED);
if (ActiveYN) //activate
{
if (Times_Through[PortNumber-1]==0)
{
// Open the log files only the first time a write event happens
// Port[PortNumber-1].OpenLogFiles(FileNames[PortNumber-1]);
Times_Through[PortNumber-1]=1;
}
SuspendCount=PortThread[PortNumber-1]->ResumeThread();
if (SuspendCount < 2)
{
b_Port_Status[PortNumber-1] = ActiveYN;
return(TRUE);
}
else
{
b_Port_Status[PortNumber-1] = FALSE;
AfxMessageBox("Unable to resume Crypto thread", MB_OK|MB_ICONEXCLAMATION , 0);
return(FALSE);
}
}
else
{
SuspendCount=PortThread[PortNumber-1]->SuspendThread();
if (SuspendCount >= 0)
{
b_Port_Status[PortNumber-1] = ActiveYN;
return(TRUE);
}
else
{
b_Port_Status[PortNumber-1] = FALSE;
AfxMessageBox("Unable to suspend Crypto thread", MB_OK|MB_ICONEXCLAMATION , 0);
return(FALSE);
}
}
}
Also, the 3 in
Executive.Set_Activate(3,!Active);
and
Executive.Set_Activate(3,Active);
has rightfully been changed to a 4.
Also, Send_Crypto_Key_1() and it's (previously unposted) brother Send_Crypto_Key_2() have been consolidated into a single Send_Crypto_Key(int key)
-
Also, since the problem has been narrowed down to and the original "odd declaration" seems to be connected to whether there were breakpoints at those locations are during debugging, I've posted a new topic ("CWinThread messing itself up") to focus in on the problem.
-
> Unfortunately I'm very new to threads and don't know how to take into account the thread API not returing a proper 'this' pointer to a C++ class member function.
I told you above.
Here is an example.
http://cboard.cprogramming.com/showt...t=class+static
Scroll down to posts #4 and #5
-
>>UINT C_Control::StartCryptoPortThread( LPVOID pParam )
Is this declared as a static function? If so, you should have nothing to worry about, because static functions act essentially the same way as global functions. There is only a problem if it is a member function (non-static). I would expect you to get an error, or at least a warning, if this is the problem though...
-
If I understand correctly, it seems Salem and Hunter2 are asking the same basic question right now, and the answer is yes,
>>UINT C_Control::StartCryptoPortThread( LPVOID pParam )
is declared static. Is that what you were referring to Salem?
-
Dunno, I can't see your screen from here, and 1 line isn't enough to extrapolate from.
Post a block of code similar to your post #3
-
Similar how? As in the same functions, just updated? Or are there other functions required?
-
Similar in scope - that is, something we can see enough of to gauge what you're doing.
-
But, what I posted in #3 is what I'm doing...
-
What you were doing in post #3 was wrong (in detail at least).
What we need to see is what it looks like NOW, following all the edits you've (allegedly) made to the code.
Simply telling us that "you've done it" just isn't good enough, because a lot of the time we find that what was said isn't what happened, or it was mis-interpreted or (well, you get the idea).
-
Code:
UINT C_Control::StartCryptoPortThread( LPVOID pParam )
{
char* buffer;
int size = 0;
C_RS_422_Port* pObject = ( C_RS_422_Port*)pParam;
if (pObject == NULL )
return 1; // if pObject is not valid
else
{
//C_Control::GetOutboundMessage(buffer,size);
pObject->Send_Crypto_Key(1); // do something with 'pObject'
return 0; // thread completed successfully
}
}
C_Control::C_Control()
{
PortThread[3]= AfxBeginThread(StartCryptoPortThread, &Port[3],THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED);
PortThreadCrypto = PortThread[3];
b_Port_Status[3]=FALSE;
b_Port_Open[3] = FALSE;
}
void Crypto_Dlg::OnBnClickedCryptoPortAct()
{
// TODO: Add your control notification handler code here
CString sString;
CButton* pButton;
const bool Active = TRUE;
if(!Executive.b_Port_Open[3] && ((CButton* )GetDlgItem(IDC_Crypto_Port_Act))->GetCheck() )
{
Executive.OpenPort(3, 7);
}
pButton = (CButton*)GetDlgItem(IDC_Crypto_Port_Act);
pButton->GetState();
if (pButton->GetCheck())
{
pButton->SetCheck(0);
pButton->SetState(0);
GetDlgItemText(IDC_Crypto_Port_Act,sString);
if (!sString.Compare("Activate"))
{
Executive.Set_Activate(4, Active);
SetDlgItemText(IDC_Crypto_Port_Act,"Deactivate");
}
else
{
Executive.Set_Activate(4,!Active);
SetDlgItemText(IDC_Crypto_Port_Act,"Activate");
}
Executive.On_Crypto_Apply_Event();
// m_b_Crypto_Port_Act = TRUE;
}
}
void C_Control::On_Crypto_Apply_Event()
{
// this function controls the thread starting and stopping.
// the threads are synchronized on a start and a stop event.
// the thread functions that this functions controls are
// those that write data to the ports and to the log files
// if port is currently inactive - start and set timing
if (!b_Port_Status[3])
{
goto startports;
}
else // port already active
{
Activate_Crypto_Port(4, FALSE);
goto startports;
}
startports:
Activate_Crypto_Port(4, TRUE);
Port[3].StartTransmission.SetEvent();
}
bool C_Control::Activate_Crypto_Port(int PortNumber, bool ActiveYN)
{
// this function starts or suspends a port thread depending
// on the state of ActiveYN and opens the log files the first
// time a port is activated
static int Times_Through[4] = {0,0,0,0};
DWORD SuspendCount;
if (ActiveYN) //activate
{
if (Times_Through[PortNumber-1]==0)
{
// Open the log files only the first time a write event happens
// Port[PortNumber-1].OpenLogFiles(FileNames[PortNumber-1]);
Times_Through[PortNumber-1]=1;
}
SuspendCount=PortThread[PortNumber-1]->ResumeThread();
if (SuspendCount < 2)
{
b_Port_Status[PortNumber-1] = ActiveYN;
return(TRUE);
}
else
{
b_Port_Status[PortNumber-1] = FALSE;
AfxMessageBox("Unable to resume Crypto thread", MB_OK|MB_ICONEXCLAMATION , 0);
return(FALSE);
}
}
else
{
SuspendCount=PortThread[PortNumber-1]->SuspendThread();
if (SuspendCount >= 0)
{
b_Port_Status[PortNumber-1] = ActiveYN;
return(TRUE);
}
else
{
b_Port_Status[PortNumber-1] = FALSE;
AfxMessageBox("Unable to suspend Crypto thread", MB_OK|MB_ICONEXCLAMATION , 0);
return(FALSE);
}
}
}
UINT C_RS_422_Port::Send_Crypto_Key(int key)
{
DWORD aword = ::WaitForMultipleObjects(2,EventHandles,FALSE,INFINITE);
//more code based on aword
}
As you can see, I haven't made many significant changes.
-
This is not quite related to your current problem, but I found this rather odd:
Code:
// if port is currently inactive - start and set timing
if (!b_Port_Status[3])
{
goto startports;
}
else // port already active
{
Activate_Crypto_Port(4, FALSE);
goto startports;
}
startports:
Activate_Crypto_Port(4, TRUE);
as it seems like a complicated way of writing:
Code:
// if port is already active - stop
if (b_Port_Status[3])
{
Activate_Crypto_Port(4, FALSE);
}
// start and set timing
Activate_Crypto_Port(4, TRUE);
-
Yeah, I agree, but I'm not the first one to get my hands on this code and I have to do what's already been done only change it slightly. So I've been copying and pasting a lot of code and that musta slipped through, thanks!
-
> PortThread[3]= AfxBeginThread(StartCryptoPortThread, &Port[3],THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED);
So where's StartCryptoPortThread ?
-
Whoops, sorry. I accidentally put in StartGPSPortThread, but I've editted the post to include StartCryptoPortThread.