Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Why does VFP have a MTDLL?
Message
From
27/01/2005 13:29:03
Joel Leach
Memorial Business Systems, Inc.
Tennessee, United States
 
 
To
27/01/2005 10:50:59
General information
Forum:
Visual FoxPro
Category:
COM/DCOM and OLE Automation
Miscellaneous
Thread ID:
00980541
Message ID:
00981326
Views:
48
David,

Thanks for that explanation. It coincides with testing I've done before. Regarding public variables and environment settings, each thread is protected using thread local storage. From VFP Help:

In addition to addressing blocking issues, implementing Apartment-model threading in the vfp7t.dll run time also eliminates conflicts in accessing global data from multiple threads by giving each apartment its own copy of global data. The vfp7t.dll uses thread local storage to give each class instance its own set of data. This means that a variable you declare PUBLIC is global only to the thread; each thread has an instance of the variable.

Note: Read-write properties of the Application object such as AutoYield are global to the project.

...

The vfp7t.dll run time automatically protects globals and user data through thread local storage, but this only applies between apartments (threads). Objects on the same thread instantiated from the same .dll are able to access each other's data. The Session class aids in data protection within the thread.


I figured this was implemented internally using a single runtime. According to Rick, a separate copy of the runtime may in fact be loaded for each thread. Although, that is the first time I've heard that. Maybe I'll send Calvin an email. It would make a good blog <g>.

>
>Some of these questions depend on how you are running the MTDLL. Let's consider this piece of code:
DEFINE CLASS MyCom AS Session OLEPUBLIC
>
>FUNCTION Sayit(MyString as String) As String
>	RETURN MyString
>ENDFUNC
>
>* useful method for reporting on runtime environment
>FUNCTION ShowEnv() As String
>
>  LOCAL lcEnv
>  TEXT TO lcEnv TEXTMERGE NOSHOW
>App Object Name: <<_vfp.Name>>
>App Object Full Name: <<_vfp.FullName>>
>COM Server Full Path Name: <<_vfp.ServerName>>
>App Start Mode: <<THIS.ShowStartMode()>>
>App Object Process ID: <<_vfp.ProcessId>>
>Thread ID: <<_vfp.ThreadId>>
>Automation Server Version: <<_vfp.Version>>
>VFP Version: <<VERSION()>>
>Unattended Server Mode: <<THIS.ShowUnattendedMode()>>
>Current Directory: <<SET("DEFAULT")+SYS(2003)>>
>Start Directory: <<SYS(2004)>>
>HOME(0): <<HOME(0)>>
>HOME(7): <<HOME(7)>>
>Resource File: <<SYS(2005)>>
>Config File/Location: <<SYS(2019)>>
>Temp File Path: <<SYS(2023)>>
>Path: <<SET("PATH")>>
>Operating System: <<OS()>>
>Computer Name/User: <<ID()>>
>PROGRAM(1): <<PROGRAM(1)>>
>PROGRAM(2): <<PROGRAM(2)>>
>  ENDTEXT
>  RETURN lcEnv
>ENDFUNC
>
>PROTECTED FUNCTION ShowStartMode() As String
>  LOCAL lnMode, lcShowMode
>  lnMode = _VFP.StartMode
>  DO CASE
>    CASE lnMode = 0
>      lcShowMode = [None]
>    CASE lnMode = 1
>      lcShowMode = [Local Server]
>    CASE lnMode = 2
>      lcShowMode = [Runtime EXE Server]
>    CASE lnMode = 3
>      lcShowMode = [Runtime DLL Server]
>    CASE lnMode = 4
>      lcShowMode = [VFP Runtime APP]
>    CASE lnMode = 5
>      lcShowMode = [Runtime MTDLL Server]
>    OTHERWISE
>      lcShowMode = []
>  ENDCASE
>  RETURN lcShowMode
>ENDFUNC
>
>PROTECTED FUNCTION ShowUnattendedMode() As String
>  LOCAL lcMode, lcShowMode
>  lcMode = SYS(2335)
>  DO CASE
>    CASE lcMode = "0"
>      lcShowMode = [Enabled - Modal States Prohibited]
>    CASE lcMode = "1"
>      lcShowMode = [Disabled - Modal States Allowed]
>    OTHERWISE
>      lcShowMode = []
>  ENDCASE
>  RETURN lcShowMode
>ENDFUNC
>
>ENDDEFINE
>
>If you put the code above into a PRG and pull it into a project named comtest, compile it as an MTDLL, then call the ShowEnv() method from inside VFP, you get the same processID and threadID as the instance of VFP you are calling it from (a DLL is an in-process server, right?). Thy this at the command window and compare the ProcessID and ThreadID reported from each instance of the MTDLL to the ones for your instance of VFP:
CLEAR
>SET MEMOWIDTH TO 120
>? _vfp.ProcessId
>? _vfp.ThreadId
>o=CREATEOBJECT("comtest.MyCom")
>? o.ShowEnv()
>o2=CREATEOBJECT("comtest.MyCom")
>? o2.ShowEnv()
>o=null
>o2=null
>
>Now, be sure to issue the two lines above to null out the references, and let's try it a different way. If you go to Component Services on your computer and create an empty COM+ Application, add the same COM DLL to that Application as a Component, then call it in two different sessions just like above, you will get both instances with the same processID as each other (but different from the VFP instance, because the DLL is being called by COM+ services) and you will get two completely DIFFERENT threadIDs -- managed for you by COM+ services).
>
>In the first case, with the COM objects running in the same thread as VFP, you can have collisions with any PUBLIC vars (and with any data that is not protected by a private datasession), so PUBLICS should be avoided unless you have a specific reason for them. However, under COM+ services, even the publics seem to be separated from each other, but I have not tested that under heavy loads -- I just avoid them.
>
>Note that the code above bases the COM object on the Session class, so I don't have to worry about one instance stepping on another instance's data files, even if running outside of COM+ services. Due to the other benefits of a better-managed COM environment, however, I like to always install in COM+ services.
>
>Some of this stuff is written down here and there, including a great old paper by Randy Brown about VFP and MTS (predecessor of COM+) and some articles in various pubs by Rick, Craig, and Claudio. I think you can still find Randy's paper on MSDN online by searching for VFP and MTS (some of that material is also now in the VFP help file). However, to really get a handle on this stuff, you have to just poke around and try for yourself. Maybe the ShowEnv() and related methods above will help out during experimentation.
Joel Leach
Microsoft Certified Professional
Blog: http://www.joelleach.net
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform