Results 1 to 17 of 17

Thread: VB6 Mutex? Need to Eliminate Race Conditions

  1. #1

    Thread Starter
    New Member
    Join Date
    Jun 2005
    Posts
    14

    VB6 Mutex? Need to Eliminate Race Conditions

    Hello,

    I have to seperate VB6 applications that are trying to perform the same operation on the same target process. That is, each VB6 application is trying to save an Excel spreadsheet at the same time. I believe this is causing our most recent errors with our application, resulting in one application being killed by the other.

    Is it possible to create mutexes in VB6? If not, can anyone any other advice as to how to eliminate this race condition?

  2. #2
    Frenzied Member I_Love_My_Vans's Avatar
    Join Date
    Jan 2005
    Location
    In the PHP compiler
    Posts
    1,275

    Re: VB6 Mutex? Need to Eliminate Race Conditions

    Um, a computer can, believe it or not only do one thing at a time, so one has saved the excel spreadsheet, and the other has to be dissapointed. I think that is how it works

    Can you not try and work around the problem by overwriting or checking to see if the file exists, and declining access if it does exist.

    ILMV

  3. #3
    Frenzied Member pnish's Avatar
    Join Date
    Aug 2002
    Location
    Tassie, Oz
    Posts
    1,918

    Re: VB6 Mutex? Need to Eliminate Race Conditions

    There is an API called CreateMutex which would suggest that you can create a mutex from VB6. Don't ask me how though! Any API gurus out there listening?
    VB Code:
    1. Private Declare Function CreateMutex Lib "kernel32.dll" Alias "CreateMutexA" _
    2.     (lpMutexAttributes As SECURITY_ATTRIBUTES, ByVal bInitialOwner As Long, ByVal lpName As String) As Long
    Pete

    No trees were harmed in the making of this post, however a large number of electrons were greatly inconvenienced.

  4. #4
    Former Admin/Moderator MartinLiss's Avatar
    Join Date
    Sep 1999
    Location
    San Jose, CA
    Posts
    33,431

    Re: VB6 Mutex? Need to Eliminate Race Conditions

    Here is an example from the API Guide which calls this code an "Advanced PrevInstance".

    VB Code:
    1. 'Code by Adam Verwijs
    2. Const ERROR_ALREADY_EXISTS = 183&
    3. Private Declare Function CreateMutex Lib "kernel32" Alias "CreateMutexA" (lpMutexAttributes As Any, ByVal bInitialOwner As Long, ByVal lpName As String) As Long
    4. Private Declare Function ReleaseMutex Lib "kernel32" (ByVal hMutex As Long) As Long
    5. Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
    6. Private Sub Form_Load()
    7.     Dim hMutex As Long
    8.     'Try to create a new Mutex
    9.     hMutex = CreateMutex(ByVal 0&, 1, App.Title)
    10.     'Did the mutex already exist?
    11.     If (Err.LastDllError = ERROR_ALREADY_EXISTS) Then
    12.         'Clean up
    13.         ReleaseMutex hMutex
    14.         CloseHandle hMutex
    15.         'More than one instance detected
    16.         MsgBox "More than one instance"
    17.         End
    18.     Else
    19.         'form load code
    20.     End If
    21. End Sub

  5. #5
    Fanatic Member
    Join Date
    Jan 2005
    Location
    In front of this pc.
    Posts
    580

    Re: VB6 Mutex? Need to Eliminate Race Conditions

    I believe you might resolve this by only allowing a single user to gain write access to the document at any time - others could open the document, if that is something to be desired, but only for reading. Perhaps the OpenFile API will help you resolve the problem....

    VB Code:
    1. Declare Function OpenFile Lib "kernel32" Alias "OpenFile" ( _
    2.     ByVal lpFileName As String, lpReOpenBuff As OFSTRUCT, _
    3.     ByVal wStyle As Long) As Long
    4.  
    5. ' some wStyle options
    6. Const OF_READ As Long = &H0 'Opens the file for reading only.
    7. Const OF_READWRITE As Long = &H2 'Opens the file for reading and writing.
    8. Const OF_SHARE_DENY_WRITE As Long = &H20 'denies write access to others
    9. Const OF_SHARE_EXCLUSIVE As Long = &H10 'denies any access to others
    10. Const OF_VERIFY As Long = &H400 'Verifies that the date and time of the file
    11. Const OF_WRITE As Long = &H1 'Opens the file for writing only
    12.  
    13. ' info for lpReOpenBuff
    14. Const OFS_MAXPATHNAME As Long = 128
    15.  
    16. Type OFSTRUCT
    17.     cBytes As Byte
    18.     fFixedDisk As Byte
    19.     nErrCode As Integer
    20.     Reserved1 As Integer
    21.     Reserved2 As Integer
    22.     szPathName(OFS_MAXPATHNAME) As Byte
    23. End Type

  6. #6
    Frenzied Member yrwyddfa's Avatar
    Join Date
    Aug 2001
    Location
    England
    Posts
    1,253

    Re: VB6 Mutex? Need to Eliminate Race Conditions

    Mutexes are kinda heavy system objects - although the code Marty posted should work fine

    Lighter (more efficient?) things to look out for are Semaphores, and Events.
    Last edited by yrwyddfa; Aug 26th, 2005 at 03:27 AM.
    "As far as the laws of mathematics refer to reality, they are not certain; and as far as they are certain, they do not refer to reality." - Albert Einstein

    It's turtles! And it's all the way down

  7. #7

    Thread Starter
    New Member
    Join Date
    Jun 2005
    Posts
    14

    Re: VB6 Mutex? Need to Eliminate Race Conditions

    Quote Originally Posted by I_Love_My_Vans
    Um, a computer can, believe it or not only do one thing at a time, so one has saved the excel spreadsheet, and the other has to be dissapointed. I think that is how it works

    Can you not try and work around the problem by overwriting or checking to see if the file exists, and declining access if it does exist.

    ILMV
    This is just flamebait... Moving on.

    To the other people who actually understand my problem and provide meaningful solutions, thank you very much. I will look into the API and sample code for mutexes. I will also check out semaphores (its been a while since I was in OS class, so I completely forgot about these).

    Also I should clarify; the two VB apps are trying to save different spreadsheets that are open in one Excel process. That is, there is a single Excel process which contains all open spreadsheets.

  8. #8
    Frenzied Member yrwyddfa's Avatar
    Join Date
    Aug 2001
    Location
    England
    Posts
    1,253

    Re: VB6 Mutex? Need to Eliminate Race Conditions

    Yeah a semaphore or event should be able to handle this quite nicely.
    "As far as the laws of mathematics refer to reality, they are not certain; and as far as they are certain, they do not refer to reality." - Albert Einstein

    It's turtles! And it's all the way down

  9. #9

    Thread Starter
    New Member
    Join Date
    Jun 2005
    Posts
    14

    Re: VB6 Mutex? Need to Eliminate Race Conditions

    Ok so my question now is, where can I find information about how to create and use a semaphore in VB6?

  10. #10
    Frenzied Member yrwyddfa's Avatar
    Join Date
    Aug 2001
    Location
    England
    Posts
    1,253

    Re: VB6 Mutex? Need to Eliminate Race Conditions

    If you can wait until tomorrow then I'll post some code. It's a bank holiday here at the moment so I'm sitting in the sun drinking beer.

    What the hell I'm doing with my laptop on reading this forum is anybodies guess . . .
    "As far as the laws of mathematics refer to reality, they are not certain; and as far as they are certain, they do not refer to reality." - Albert Einstein

    It's turtles! And it's all the way down

  11. #11

    Thread Starter
    New Member
    Join Date
    Jun 2005
    Posts
    14

    Re: VB6 Mutex? Need to Eliminate Race Conditions

    You just love VB6 I guess....

  12. #12
    Fanatic Member BrianHawley's Avatar
    Join Date
    Aug 2001
    Location
    Saudi Arabia
    Posts
    796

    Re: VB6 Mutex? Need to Eliminate Race Conditions

    We often use a plain text flag file for this sort of thing. i.e. a situation with no inbuilt locking protocols.

    Try to create/open the flag file for read/write. If it opens, put the current user name in the file, do the task, then close/delete the file.

    If it fails, optionally open as read only and see which user has the lock. Feed back to the application user if required.

    This has the advantage of using a file lock, which will clear automatically (eventually) if somebody locks the file then crashes off the network without unlocking it.

    Sorry no code as I'm away from the office, but can post tomorrow if you need it.
    Brian
    (Fighting with the RightToLeft bugs in VS 2005)

  13. #13

    Thread Starter
    New Member
    Join Date
    Jun 2005
    Posts
    14

    Re: VB6 Mutex? Need to Eliminate Race Conditions

    Thanks, I've tried implementing the following code:
    Code:
        hMutex = CreateMutex(ByVal 0&, True, "BDP")
        'Did the mutex already exist?
        While (Err.LastDllError = ERROR_ALREADY_EXISTS)
            Call out.Display("Waiting for the mutex...", True, True)
            Sleep (10000)
            hMutex = OpenMutex(ByVal 0&, True, "BDP")
           
        Wend
        ...
        ...
        ...
        ReleaseMutex hMutex
    I put a spinlock so one process should wait until another one has released the mutex. However, I believe the OpenMutex line is throwing me off. Any ideas?

  14. #14

    Thread Starter
    New Member
    Join Date
    Jun 2005
    Posts
    14

    Re: VB6 Mutex? Need to Eliminate Race Conditions

    Thanks, I've tried implementing the following code:
    Code:
        hMutex = CreateMutex(ByVal 0&, True, "BDP")
        'Did the mutex already exist?
        While (Err.LastDllError = ERROR_ALREADY_EXISTS)
            Call out.Display("Waiting for the mutex...", True, True)
            Sleep (10000)
            hMutex = OpenMutex(ByVal 0&, True, "BDP")
           
        Wend
        ...
        ...
        ...
        ReleaseMutex hMutex
    I put a spinlock so one process should wait until another one has released the mutex. However, I believe the OpenMutex line is throwing me off. Any ideas?

  15. #15
    Frenzied Member yrwyddfa's Avatar
    Join Date
    Aug 2001
    Location
    England
    Posts
    1,253

    Re: VB6 Mutex? Need to Eliminate Race Conditions

    I changed my mind and now believe that an 'event' is probably the best way forward for this particular task.

    Please find attached a class 'CFilelock'

    VB Code:
    1. Option Explicit
    2.  
    3. '***************************
    4. '* Win32 Declarations . . .
    5. '***************************
    6. Private Declare Function OpenEventW Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal lpName As Long) As Long
    7. Private Declare Function CreateEventW Lib "kernel32" (lpEventAttriutes As Long, ByVal bManualReset As Long, ByVal bInitialState As Long, ByVal lpName As Long) As Long
    8. Private Declare Function ResetEvent Lib "kernel32" (ByVal hEvent As Long) As Long
    9. Private Declare Function SetEvent Lib "kernel32" (ByVal hEvent As Long) As Long
    10. Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
    11. Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
    12.  
    13. '************************
    14. '* Win32 Constants . . .
    15. '************************
    16. Private Const WAIT_ABANDONED As Long = &H80
    17. Private Const WAIT_OBJECT_0 As Long = &H0
    18. Private Const WAIT_TIMEOUT As Long = &H102
    19.  
    20. '**************************
    21. '* Local state stuff . . .
    22. '**************************
    23. Private mFile As String
    24. Private mhEvent As Long
    25. Private mTimeout As Long
    26. Private mRetry As Long
    27.  
    28. Private Sub Class_Initialize()
    29.     mTimeout = 100
    30.     mRetry = 3
    31. End Sub
    32.  
    33. Private Sub Class_Terminate()
    34.     CloseHandle mhEvent
    35. End Sub
    36.  
    37. Public Property Let File(Name As String)
    38.     mFile = Name
    39. End Property
    40.  
    41. Public Property Get File() As String
    42.     File = mFile
    43. End Property
    44.  
    45. Public Property Let Timeout(Milliseconds As Long)
    46.     mTimeout = Milliseconds
    47. End Property
    48.  
    49. Public Property Get Timeout() As Long
    50.     Timeout = mTimeout
    51. End Property
    52.  
    53. Public Property Let Retry(Num As Long)
    54.     mRetry = Num
    55. End Property
    56.  
    57. Public Property Get Retry() As Long
    58.     Retry = mRetry
    59. End Property
    60.  
    61. Public Function LockFile() As Boolean
    62.  
    63.     On Error GoTo ERR_Lockfile
    64.    
    65.     Dim lWait As Long
    66.     Dim i As Long
    67.    
    68.     '**********************************************************************
    69.     '* Try to get a handle to the event. If we can't then create one . . .
    70.     '**********************************************************************
    71.     mhEvent = OpenEventW(0&, False, StrPtr(mFile))
    72.     If Not mhEvent Then
    73.         mhEvent = CreateEventW(0&, True, True, StrPtr(mFile))
    74.     End If
    75.    
    76.     '**********************************************
    77.     '* Wait for the event to become signalled . . .
    78.     '**********************************************
    79.     For i = 1 To mRetry
    80.  
    81.         '**********************************************
    82.         '* Wait for the event to become signalled . . .
    83.         '**********************************************
    84.         lWait = WaitForSingleObject(mhEvent, mTimeout)
    85.        
    86.         '****************************************************************
    87.         '* The event has become signalled. We need to now set it to be
    88.         '* non signalled so we have a lock on the event . . .
    89.         '****************************************************************
    90.         If lWait = WAIT_OBJECT_0 Then
    91.             ResetEvent mhEvent
    92.             LockFile = True
    93.             Exit For
    94.         End If
    95.    
    96.     Next
    97.    
    98.     Exit Function
    99.    
    100. ERR_Lockfile:
    101.     CloseHandle mhEvent
    102.     Err.Raise Err.Number, Err.Source, Err.Description, Err.HelpFile, Err.HelpContext
    103. End Function
    104.  
    105. Public Sub ReleaseFile()
    106.  
    107.     On Error GoTo ERR_ReleaseFile
    108.    
    109.     '******************************************************************
    110.     '* Set the event to be signalled so other processes wait functions
    111.     '* return immediately . . .
    112.     '******************************************************************
    113.     SetEvent mhEvent
    114.     CloseHandle mhEvent
    115.    
    116.     Exit Sub
    117.    
    118. ERR_ReleaseFile:
    119.     Err.Raise Err.Number, Err.Source, Err.Description, Err.HelpFile, Err.HelpContext
    120. End Sub
    "As far as the laws of mathematics refer to reality, they are not certain; and as far as they are certain, they do not refer to reality." - Albert Einstein

    It's turtles! And it's all the way down

  16. #16
    Frenzied Member yrwyddfa's Avatar
    Join Date
    Aug 2001
    Location
    England
    Posts
    1,253

    Re: VB6 Mutex? Need to Eliminate Race Conditions

    One little caveat: only for Win2k or later machines (unless the Unicode platform is installed)
    "As far as the laws of mathematics refer to reality, they are not certain; and as far as they are certain, they do not refer to reality." - Albert Einstein

    It's turtles! And it's all the way down

  17. #17

    Thread Starter
    New Member
    Join Date
    Jun 2005
    Posts
    14

    Re: VB6 Mutex? Need to Eliminate Race Conditions

    Thanks yrwyddfa,

    I stuck with the mutexes, but I used your code as inspiration. Everything works great and our 3 VB apps now seem to play nice with each other.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width