<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML><HEAD><META http-equiv=Content-Type content="text/html; charset=iso-8859-1"><META content="MSHTML 6.00.2800.1528" name=GENERATOR><STYLE></STYLE></HEAD><BODY bgColor=#ffffff><DIV><FONT face=Arial size=2>Hello all</FONT></DIV><DIV><FONT face=Arial size=2></FONT> </DIV><DIV><FONT face=Arial size=2>I have a question that may be only the VEE people would know (or Shawn ).</FONT></DIV><DIV><FONT face=Arial size=2></FONT> </DIV><DIV><FONT face=Arial size=2>We use an ActiveX UEI Framework library. This fires events when acquired data is available or an error occurs.</FONT></DIV><DIV><FONT face=Arial size=2></FONT> </DIV><DIV><FONT face=Arial size=2>We have created a wrapper ActiveX DLL for this UEI library and it sits as a layer between the UEI DLL and the host VEE program. VEE polls the wrapper library to get a "DataAvailable" status and to get data from the wrapper DLL.</FONT></DIV><DIV><FONT face=Arial size=2></FONT> </DIV><DIV><FONT face=Arial size=2>The strange thing is that events fired by the UEI Framework are handled by our wrapper DLL even when the host VEE program is stopped (development mode). I also noticed that the thread ID (API GetCurrentThreadID) is the same in the event handler and the host VEE program. I guess this means that VEE is 'interrupted (even when program is stopped) to service the event. Is this right?</FONT></DIV><DIV><FONT face=Arial size=2></FONT> </DIV><DIV><FONT face=Arial size=2>We are seeing some strange errors and we're not sure why. I think that during a VEE call to a wrapper "GetStatus" / "GetData" function, the wrapper function is interrupted by an event fired by the UEI Framework, and then there are 2 Wrapper DLL functions running at the same time accessing the same data and causing errors (complete program lock-ups). </FONT></DIV><DIV><FONT face=Arial size=2></FONT> </DIV><DIV><FONT face=Arial size=2>Visual Basic is supposed to be 'thread safe' and should prevent 2 functions running at the same time, but VEE may be changing this.</FONT></DIV><DIV><FONT face=Arial size=2></FONT> </DIV><DIV><FONT face=Arial size=2>Can anyone shed any light on this scenario? Would the wrapper DLL still be 'thread safe' when used with VEE?</FONT></DIV><DIV><FONT face=Arial size=2></FONT> </DIV><DIV><FONT face=Arial size=2>We're using VEE6.03, Visual Basic 6 (SP5), WinXP (SP2)</FONT></DIV><DIV><FONT face=Arial size=2></FONT> </DIV><DIV><FONT face=Arial size=2></FONT> </DIV><DIV><FONT face=Arial size=2>Thanks for any help.</FONT></DIV><DIV><FONT face=Arial size=2></FONT> </DIV><DIV><FONT face=Arial size=2></FONT> </DIV><DIV><FONT face=Arial size=2>Andrew Fudge</FONT></DIV><DIV><FONT face=Arial size=2>Genesys Test Engineering</FONT></DIV><DIV><FONT face=Arial size=2>Wales, UK</FONT></DIV><BR>---<BR>You are currently subscribed to vrf as: rsb@soco.agilent.com<BR>To subscribe send an email request to "owner-vrf@it.lists.it.agilent.com".<BR>To unsubscribe send a blank email to "leave-vrf@it.lists.it.agilent.com".<BR>To send messages to this mailing list, email "vrf@agilent.com". <BR>If you need help with the mailing list send a message to "owner-vrf@it.lists.it.agilent.com".<BR>Search the "unofficial vrf archive" at "www.oswegosw.com/vrf_archive/".</BODY></HTML>
> for this UEI library and it sits as a
> layer between the UEI DLL and the host
> VEE program.
Ok.
> The strange thing is that events fired
> by the UEI Framework are handled by our
> wrapper DLL even when the host VEE program
> is stopped (development mode).
Expected behavior! Your wrapper subscribes to events published by this
library. As long as the library is firing events, your wrapper will receive
them.
> I also noticed that the thread ID (API
> GetCurrentThreadID) is the same in the
> event handler and the host VEE program.
Yes indeedy (or at least, most probably. This is the default way to do
things). When a subscriber subscribes to an event, the actual call the
publisher makes (to the COM subsystem) is on the publisher's thread. The
call to the subscriber is made on a system thread (COM's) and received on
the subscriber's thread. This is the Apartment Threading model. You're
seeing the receiver. See:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncomg/html
/comthreading.asp
> I guess this means that VEE is 'interrupted
> (even when program is stopped) to service the
> event. Is this right?
The call from COM to VEE will most certainly be made. Whether or not VEE
does anything with it is VEE's business, but as a matter of fact you are
right. For instance, if you subclass VEE's main window (using an event to
pass messages up to VEE before returning) and then the VEE program stops,
the message processing function will still be called and executed.
> I think that during a VEE call to a wrapper
> "GetStatus" / "GetData" function, the
> wrapper function is interrupted by an event
> fired by the UEI Framework, and then there
> are 2 Wrapper DLL functions running at the
> same time accessing the same data and
> causing errors (complete program lock-ups).
Weirdness such as this is possible. Personally I think you're right. One
thing you can do to diagnose stuff like this is to log function start/stop
time along with thread id to a debug window. GetTickCount is good enough.
There are definitely different threads involved. If the wrapper data receive
starts running before GetData is done, then yup you need a mutex.
In general, any time multiple threads are accessing the same buffers, you
have to serialize access yourself. This will slow down overall response, but
there are ways to get around that.
> Visual Basic is supposed to be 'thread
> safe' and should prevent 2 functions
> running at the same time, but VEE may
> be changing this.
In effect yes, VEE is changing it. VB is thread safe as long as it doesn't
have to deal with multiple threads out of the context of COM (I'm not
kidding! I know you'll find claims to the contrary all over the net. The
fact is these claims are bogus. Been there, done that, crashed & burned). In
VB's own little world it is safe - in the context of COM it is safe, but
when you start throwing threads in there from out of the blue, it can't
handle it.
Try this: create a Win32 thread from Visual Basic with CreateThread. You
have just violated VB's supposed thread safety. Nearly anything you do on
either thread that calls the CRT will almost certainly crash the VB
execution engine. Compiled VB is a bunch of calls to the VB runtime, which
are in turn calls to the CRT or Windows API. The problem is that those calls
are made through the execution engine and it is not thread safe at all. You
get different threads running in there that are not in different apartments
and you've got big, big trouble.
If your project were all VB, using all COM, then there wouldn't be a
problem.
> Can anyone shed any light on this
> scenario? Would the wrapper DLL still
> be 'thread safe' when used with VEE?
As long as you're not mixing threads it's cool, but since you are all you
have to do is provide your own thread safety and all your problems will go
away.
Multithreading 101
Think of your wrapper as having an input side and an output side. The events
you subscribe to in the original library are those on the input side. The
events you publish to VEE are those on the output side. Whatever functions
you provide to VEE (like GetStatus & GetData) are on the output side.
Likewise, any calls you make as a result of receiving events from the
original library are on the input side.
Provide a global ghMutex in a module. In Class_Initialize, check to see of
the value of ghMutex is 0. If it is, ghMutex = CreateMutex(0&, 0, 0&). Upon
entry to *any* input or output function (where resources shared between
input and output will be accessed), WaitForSingleObject(ghMutex, -1). At the
end of the function (when resource access is over), ReleaseMutex(ghMutex).
In Class_Terminate, CloseHandle(ghMutex) and ghMutex = 0.
Take care to acquire the mutex only once on either side. For instance, an
event arrives, and in the handler you do something like:
WaitForSingleObject(ghMutex, -1)
status = GetStatusFromEUI()
If status And STS_DATA_READY = STS_DATA_READY Then
data = GetDataFromEUI()
End If
ReleaseMutex(ghMutex)
Then GetStatusFromEUI and GetDataFromEUI cannot call WaitForSingleObject
because you already own the mutex - the wait will wait forever.
If speed is an issue (but it's probably not since ActiveX is in there in the
first place) you can always double buffer the data. You *can* use
RtlMoveMemory to move stuff around, but you'd probably want to set up an
explicit rep movsd to get it done as fast as possible.
There can of course be other answers to your problem. For instance, you
might want to make a buffer an object and pass it to VEE along with the
event. In this case there is no shared memory and the problem doesn't arise.
IOW your wrapper becomes more of an assembly line than a way-station.
Execution flows in a circle rather than having an input side and an output
side. That's a much more COM solution.
-SHAWN-
---
You are currently subscribed to vrf as: rsb@soco.agilent.com
To subscribe send an email request to "owner-vrf@it.lists.it.agilent.com".
To unsubscribe send a blank email to "leave-vrf@it.lists.it.agilent.com".
To send messages to this mailing list, email "vrf@agilent.com".
If you need help with the mailing list send a message to "owner-vrf@it.lists.it.agilent.com".
Search the "unofficial vrf archive" at "www.oswegosw.com/vrf_archive/".