Microsoft KB Archive/300850

= BUG: GlobalMultiUse Class Does Not Terminate in Multithreaded Environment =

Article ID: 300850

Article Last Modified on 10/21/2005

-

APPLIES TO


 * Microsoft Visual Studio 6.0 Service Pack 4
 * Microsoft Visual Studio 6.0 Service Pack 5
 * Microsoft Visual Basic 6.0 Enterprise Edition Service Pack 4
 * Microsoft Visual Basic 6.0 Enterprise Edition Service Pack 5
 * Microsoft Visual Basic 6.0 Professional Edition

-



This article was previously published under Q300850



SYMPTOMS
When two clients call a procedure of an ActiveX EXE component at the same time, and this procedure calls another procedure of a MultiUse class in an ActiveX dynamic-link library (DLL), if this class accesses a procedure in a GlobalMultiUse class in another ActiveX DLL, the ActiveX EXE component stays in memory; that is, the process fails to terminate, even after all the references to it have been released.

This behavior does not occur in Visual Basic 6.0 Service Pack 3 (SP3) or earlier.



CAUSE
This problem occurs because the DllCanUnloadNow function of the GlobalMultiUse DLL returns FALSE if it is currently being called by another thread. This means that the GlobalMultiUse DLL may not be able to release itself in a multithreaded environment.



RESOLUTION
A supported hotfix is now available from Microsoft, but it is only intended to correct the problem that this article describes. Apply it only to systems that are experiencing this specific problem.

Note You must have a Visual Studio license agreement to obtain this hotfix.

To resolve this problem, contact Microsoft Product Support Services to obtain the hotfix. For a complete list of Microsoft Product Support Services telephone numbers and information about support costs, visit the following Microsoft Web site:

http://support.microsoft.com/contactus/?ws=support

Note In special cases, charges that are ordinarily incurred for support calls may be canceled if a Microsoft Support Professional determines that a specific update will resolve your problem. The usual support costs will apply to additional support questions and issues that do not qualify for the specific update in question. The English version of this fix should have the following file attributes or later:

  Date         Time        Version    Size     File name -  29 May 2001  3:32:23 PM  6.0.92.37  1.32 MB  Msvbvm60.dll



STATUS
Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article.



Create the DLL with a GlobalMultiUse Class
 Create a new ActiveX DLL project with a default class, Class1. From the Project menu, click Project1 Properties. Change the project name to GMultiUseDll, and then click OK. In the Properties dialog box, set the Instancing property of Class1 to 6 - GlobalMultiUse.  Copy and paste the following code to Class1's code module: Public Function ClassName As String ClassName = &quot;Class1&quot; End Function  From the File menu, click Make GMultiUseDll.dll to compile the project. GMultiUseDll.dll is created.</li></ol>

Create the DLL with a MultiUse Class
<ol> Create a new ActiveX DLL project with a default class, Class1.</li> From the Project menu, click Project1 Properties. Change the project name to MultiUseDll, and then click OK.</li> From the Project menu, click References, select the GMultiUseDll.dll check box, and then click OK.</li>  Copy and paste the following code to Class1's code module: Public Function GetString As String GetString = ClassName End Function </li> From the File menu, click Make MultiUseDll.dll to compile the project. MultiUseDll.dll is created.</li></ol>

Create the ActiveX EXE Project
<ol> Create a new ActiveX EXE project with a default class, Class1.</li> From the Project menu, click Project1 Properties. Change the project name to TestServer, and then click OK.</li> From the Project menu, click References, select the MultiUseDll.dll check box, and then click OK.</li> From the Project menu, click TestServer Properties. On the General tab, set the Thread Pool to 10 threads.</li>  Copy and paste the following code to Class1's code module Public Sub DoSomething Dim obj As MultiuseDll.Class1 Set obj = New MultiuseDll.Class1 obj.GetString End Sub </li> From the File menu, click Make TextServer.exe to compile the project. TextServer.exe is created.</li></ol>

Create the Client Project
<ol> Create a new Standard EXE project with a default form, Form1.</li> From the Project menu, click Project1 Properties. Change the project name to TestClient, and then click OK.</li> Add a Label (Label1), a TextBox (Text1) and two CommandButtons (Command1 and Command2) to Form1.</li>  Copy and paste the following code to Form1's code module: Dim bStop As Boolean

Private Sub Command1_Click Dim oServer As Object Set oServer = CreateObject(&quot;TestServer.Class1&quot;) WaitTRUEinFile Text1.Text oServer.DoSomething Set oServer = Nothing Label1.Caption = &quot;The reference was released&quot; End Sub

' The purpose of this function is to synchronize the call to the ' GlobalMultiUse DLL through the file Sync.txt. Private Sub WaitTRUEinFile(sFile As String) Dim sFlag     As String Label1.Caption = &quot;Waiting for 'TRUE' in &quot; & sFile Do While bStop = False Open sFile For Input As #1 Line Input #1, sFlag Close #1 If UCase(Trim(sFlag)) = &quot;TRUE&quot; Then Exit Do       End If        DoEvents Loop End Sub

Private Sub Command2_Click bStop = True End Sub

Private Sub Form_Load Text1.Text = &quot;c:\sync.txt&quot; Command1.Caption = &quot;Start&quot; Command2.Caption = &quot;Stop&quot; bStop = False End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer) bStop = True End Sub </li> <li>From the File menu, click Make TestClient.exe to compile the project. TestClient.exe is created.</li></ol>

Run the Test

 * 1) Open Notepad. Add the letter &quot;t&quot; to the first position, and save the file as Sync.txt in the root of drive C.
 * 2) Start two instances of TestClient.exe. Notice that two TestClient.exe processes are running in Task Manager.
 * 3) Click Start for both instances of TestClient.
 * 4) Open Sync.txt. Change the first line to &quot;true,&quot; and save.

After you save the file, notice the TestServer.exe process in Task Manager.
 * 1) Click Stop for both instances of TestClient, and close the forms. Notice that there are no instances of TestClient.exe running. At this point, TestServer.exe stays loaded.

For additional information on issues related to multithreading in Visual Basic, click the article number below to view the article in the Microsoft Knowledge Base:

241896 PRB: Threading Issues with Visual Basic 6.0 ActiveX Components

Additional query words: multi-thread

Keywords: kbbug kbqfe kblocalsvr kbpending KB300850

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.