Announcement

Collapse

Forum Guidelines

This forum is for finished source code that is working properly. If you have questions about this or any other source code, please post it in one of the Discussion Forums, not here.
See more
See less

Sharing Data between Processes

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Sharing Data between Processes

    This is the second sample I wrote. It is a sample about two processes communicating with each other. One is sending data to another thru slots in named mapping in shared memory. This sample consists of two programs - sender and reader.

    Hope these will help if somebody begins to study memory mapped files and sharing memory between processes. Commenting is minimal but actually both programs are rather short and consist mainly of API calls. With them the help file can be consulted.

    Start both programs and watch data fly - I hope

    Lasse Rantanen
    [email protected]

    Code:
    '=================== Program SENDER.BAS ========================================
    #COMPILE EXE
    #REGISTER NONE
    #INCLUDE "Win32Api.Inc"
     
    %PAGE_READWRITE         = &H004
     
    %IDL_MSG                = 100
    %IDB_CLOSE              = 101
     
    GLOBAL g_hDlg               AS LONG
    GLOBAL g_bDone              AS INTEGER
    GLOBAL g_ptrBufferOrig      AS BYTE PTR
    GLOBAL g_hSenderSemaphore   AS LONG
    GLOBAL g_hReaderSemaphore   AS LONG
    GLOBAL g_dwTotalSends       AS DWORD
     
    DECLARE SUB SendData()
     
    '==============================================================================
    CALLBACK FUNCTION DlgProc
     
        SELECT CASE CBMSG
     
            CASE %WM_DESTROY
                g_bDone = %TRUE
     
            CASE %WM_COMMAND
     
                SELECT CASE CBWPARAM
     
                    CASE %IDB_CLOSE
                        DIALOG END CBHNDL
     
                END SELECT
     
        END SELECT
     
    END FUNCTION
     
    '==============================================================================
    FUNCTION PBMAIN()
     
        LOCAL dwResult      AS DWORD
     
        DIALOG NEW 0 ,"Writing to Shared Memory", _
                   100, 100, 200, 100, _
                   %WS_SYSMENU TO g_hDlg
     
        CONTROL ADD LABEL,   g_hDlg, %IDL_MSG, "Waiting for data request", _
                             10, 5, 170, 50
     
        CONTROL ADD BUTTON,  g_hDlg, %IDB_CLOSE, "Close",  _
                             60, 65, 80, 14
     
        DIALOG SHOW MODELESS g_hDlg CALL DlgProc
     
        WHILE NOT g_bDone
            ' Is reader process ready to accept data?
            dwResult = WaitForSingleObject(g_hSenderSemaphore, 100)
     
            IF dwResult <> %WAIT_TIMEOUT THEN
                SendData
            END IF
     
            DIALOG DOEVENTS
     
            IF g_bDone <> 0 THEN EXIT LOOP
     
        WEND
     
        MSGBOX "Sent totally " + STR$(g_dwTotalSends) + " packages"
     
        ' Clean up by closing all handles
        UnmapViewOfFile g_ptrBufferOrig
        CloseHandle g_hSenderSemaphore
        CloseHandle g_hReaderSemaphore
     
    END FUNCTION
    '==============================================================================
    SUB SendData()
     
        STATIC dwMsgSize             AS DWORD
        STATIC dwNumMsgs             AS DWORD
        STATIC dwBufferSize          AS DWORD
        STATIC szBufferName          AS ASCIIZ*%MAX_PATH
        STATIC szSenderSemaphoreName AS ASCIIZ*%MAX_PATH
        STATIC szReaderSemaphoreName AS ASCIIZ*%MAX_PATH
        STATIC hMemory               AS LONG
        LOCAL  dwErrorCode           AS DWORD
     
        STATIC nCount                AS INTEGER
        LOCAL  sTemp                 AS STRING
        LOCAL  ptrTemp               AS BYTE PTR
        LOCAL  ptrBuffer             AS BYTE PTR
        LOCAL  i                     AS INTEGER
        STATIC bInitialized          AS INTEGER
     
        IF NOT bInitialized THEN
            dwMsgSize = 100
            dwNumMsgs = 10
            dwBufferSize = dwNumMsgs * dwMsgSize
            szBufferName = "ShareBufferName"
            szSenderSemaphoreName = "Sender_Semaphore"
            szReaderSemaphoreName = "Reader_Semaphore"
     
            ' Create (or open) semaphores thru which processes communicate
            ' Semaphore informing sender about presence of reader process
            ' and its possibility to accept data
            g_hSenderSemaphore = CreateSemaphore(BYVAL %NULL, _
                                                 0, _
                                                 1, _
                                                 BYVAL VARPTR(szSenderSemaphoreName))
     
            dwErrorCode = GetLastError()
            IF (g_hSenderSemaphore = %NULL) THEN
                MSGBOX "Failed to create " + szSenderSemaphoreName + $CrLf + $CrLf +_
                       "ERROR " + STR$(dwErrorCode)
                EXIT SUB
            END IF
     
            ' Semaphore informing reader process about availability of data
            g_hReaderSemaphore = CreateSemaphore(BYVAL %NULL, _
                                                 0, _
                                                 1, _
                                                 BYVAL VARPTR(szReaderSemaphoreName))
    
            dwErrorCode = GetLastError()
     
            IF (g_hReaderSemaphore = %NULL) THEN
                MSGBOX "Failed to create " + szReaderSemaphoreName + $CrLf + $CrLf +_
                       "ERROR " + STR$(dwErrorCode)
                CloseHandle g_hSenderSemaphore
                EXIT SUB
            END IF
     
            ' Create a named mapping for our buffer backed up by swap file
            hMemory = CreateFileMapping(&HFFFFFFFF, _
                                        BYVAL %NULL, _
                                        %PAGE_READWRITE, _
                                        0, _
                                        BYVAL dwBufferSize, _
                                        szBufferName)
     
            dwErrorCode = GetLastError()
            IF (hMemory = %NULL) THEN
                MSGBOX "Failed to create file mapping for " + szBufferName + $CrLf + $CrLf +_
                       "ERROR " + STR$(dwErrorCode)
                CloseHandle g_hSenderSemaphore
                CloseHandle g_hReaderSemaphore
                EXIT SUB
            END IF
     
            ' Map our buffer
            ptrBuffer = MapViewOfFile( hMemory, _
                                       %FILE_MAP_WRITE, _
                                       BYVAL 0, _
                                       BYVAL 0, _
                                       BYVAL dwBufferSize)
     
            dwErrorCode = GetLastError()
            IF (ptrBuffer = 0) THEN
                MSGBOX "Failed to map " + szBufferName + $CrLf + $CrLf +_
                       "ERROR " + STR$(dwErrorCode)
                CloseHandle g_hSenderSemaphore
                CloseHandle g_hReaderSemaphore
                EXIT SUB
            END IF
     
            ' Remember where we created the buffer
            g_ptrBufferOrig = ptrBuffer
     
            bInitialized = %TRUE
     
        END IF
     
        ' Create message and copy it to the shared memory at next location.
        ' These locations form a ring buffer
        sTemp = "Data #" + STR$(nCount+1) + ": " + TIME$
        ptrTemp = STRPTR(sTemp)
        ptrBuffer = g_ptrBufferOrig + nCount*dwMsgSize
        FOR i = 0 TO LEN(sTemp) - 1
            @ptrBuffer = @ptrTemp
            INCR ptrBuffer
            INCR ptrTemp
        NEXT
     
        INCR g_dwTotalSends
     
        CONTROL SET TEXT g_hDlg, %IDL_MSG, "Sent to buffer #" + STR$(nCount + 1) + $CrLf + _
                                           sTemp + $CrLf+ $CrLf + _
                                           "# of packages sent is " + STR$(g_dwTotalSends)
        INCR nCount
        IF nCount > dwNumMsgs - 1 THEN nCount = 0
     
        ' Tell the reader process that one message has been sent
        ReleaseSemaphore g_hReaderSemaphore, 1, %NULL
     
    END SUB
    '================== END OF SENDER.BAS =========================================
     
    '================== Program READER.BAS ========================================
    #COMPILE EXE
    #REGISTER NONE
    #INCLUDE "Win32Api.Inc"
     
    %PAGE_READWRITE             = &H004
     
    %IDL_MSG                    = 100
    %IDB_CLOSE                  = 101
     
    GLOBAL g_hDlg               AS LONG
    GLOBAL g_bDone              AS INTEGER
    GLOBAL g_ptrBufferOrig      AS BYTE PTR
    GLOBAL g_hSenderSemaphore   AS LONG
    GLOBAL g_hReaderSemaphore   AS LONG
    GLOBAL g_dwTotalReads          AS DWORD
     
    DECLARE SUB ReadData()
     
    '==============================================================================
    CALLBACK FUNCTION DlgProc
     
        SELECT CASE CBMSG
     
            CASE %WM_DESTROY
                g_bDone = %TRUE
     
            CASE %WM_COMMAND
     
                SELECT CASE CBWPARAM
     
                    CASE %IDB_CLOSE
                        DIALOG END CBHNDL
     
                END SELECT
     
        END SELECT
     
    END FUNCTION
     
    '==============================================================================
    FUNCTION PBMAIN()
     
        LOCAL dwResult      AS DWORD
     
        DIALOG NEW 0 ,"Reading from Shared Memory", _
                   400, 100, 200, 100, _
                   %WS_SYSMENU TO g_hDlg
     
        CONTROL ADD LABEL,   g_hDlg, %IDL_MSG, "", _
                             10, 5, 170, 50
     
        CONTROL ADD BUTTON,  g_hDlg, %IDB_CLOSE, "Close",  _
                             60, 65, 80, 14
     
        DIALOG SHOW MODELESS g_hDlg CALL DlgProc
     
        WHILE NOT g_bDone
     
            DIALOG DOEVENTS
     
            ' Has sender sent some data?
            dwResult = WaitForSingleObject(g_hReaderSemaphore, 100)
     
            IF dwResult <> %WAIT_TIMEOUT THEN
                ReadData
            ELSE
                CONTROL SET TEXT g_hDlg, %IDL_MSG, "Waiting for data"
            END IF
     
            IF g_bDone <> 0 THEN EXIT LOOP
     
        WEND
     
        MSGBOX "Received totally " + STR$(g_dwTotalReads) + " packages"
     
        ' Clean up by closing all handles or at least decrement their refence count    
        UnmapViewOfFile g_ptrBufferOrig
        CloseHandle g_hSenderSemaphore
        CloseHandle g_hReaderSemaphore
     
    END FUNCTION
     
    '==============================================================================
    SUB ReadData()
     
        STATIC dwMsgSize             AS DWORD
        STATIC dwNumMsgs             AS DWORD
        STATIC dwBufferSize          AS DWORD
        STATIC szBufferName          AS ASCIIZ*%MAX_PATH
        STATIC szSenderSemaphoreName AS ASCIIZ*%MAX_PATH
        STATIC szReaderSemaphoreName AS ASCIIZ*%MAX_PATH
        STATIC hMemory               AS LONG
        LOCAL  dwErrorCode           AS DWORD
    
        STATIC nCount                AS INTEGER
        LOCAL  sTemp                 AS STRING
        LOCAL  ptrTemp               AS BYTE PTR
        LOCAL  ptrBuffer             AS BYTE PTR
        LOCAL  i                     AS INTEGER
        STATIC bInitialized          AS INTEGER
     
        IF NOT bInitialized THEN
            dwMsgSize = 100
            dwNumMsgs = 10
            dwBufferSize = dwNumMsgs * dwMsgSize
            szBufferName = "ShareBufferName"
            szSenderSemaphoreName = "Sender_Semaphore"
            szReaderSemaphoreName = "Reader_Semaphore"
     
            ' Open (or create) semaphore informing sender about the presence and
            ' readiness of the reader process         
            g_hSenderSemaphore = CreateSemaphore(BYVAL %NULL, _
                                                 0, _ 
                                                 1, _
                                                 BYVAL VARPTR(szSenderSemaphoreName))
     
            dwErrorCode = GetLastError()
            IF (g_hSenderSemaphore = %NULL) THEN
                MSGBOX "Failed to create " + szSenderSemaphoreName + $CrLf + $CrLf +_
                       "ERROR " + STR$(dwErrorCode)
                EXIT SUB
            END IF
    
            ' Semaphore informing reader process about availability of data
            g_hReaderSemaphore = CreateSemaphore(BYVAL %NULL, _
                                                 0, _
                                                 1, _ 
                                                 BYVAL VARPTR(szReaderSemaphoreName))
     
            dwErrorCode = GetLastError()
     
            IF (g_hReaderSemaphore = %NULL) THEN
                MSGBOX "Failed to create " + szReaderSemaphoreName + $CrLf + $CrLf +_
                       "ERROR " + STR$(dwErrorCode)
                CloseHandle g_hSenderSemaphore
                EXIT SUB
            END IF
    
            ' Open (or create) a named file mapping backed by swap file 
            hMemory = CreateFileMapping(&HFFFFFFFF, _
                                        BYVAL %NULL, _
                                        %PAGE_READWRITE, _
                                        0, _
                                        BYVAL dwBufferSize, _
                                        szBufferName)
     
            dwErrorCode = GetLastError()
            IF (hMemory = %NULL) THEN
                MSGBOX "Failed to create file mapping for " + szBufferName + $CrLf + $CrLf +_
                       "ERROR " + STR$(dwErrorCode)
                CloseHandle g_hSenderSemaphore
                CloseHandle g_hReaderSemaphore
                EXIT SUB
            END IF
    
            ' Create a view of our buffer into the mapping 
            ptrBuffer = MapViewOfFile( hMemory, _
                                       %FILE_MAP_WRITE, _
                                       BYVAL 0, _
                                       BYVAL 0, _
                                       BYVAL dwBufferSize)
     
            dwErrorCode = GetLastError()
            IF (ptrBuffer = 0) THEN
                MSGBOX "Failed to map " + szBufferName + $CrLf + $CrLf +_
                       "ERROR " + STR$(dwErrorCode)
                CloseHandle g_hSenderSemaphore
                CloseHandle g_hReaderSemaphore
                EXIT SUB
            END IF
    
            ' Remember where our buffer is 
            g_ptrBufferOrig = ptrBuffer
     
            bInitialized = %TRUE
     
        END IF
    
        ' Copy sent data intoa string
        sTemp = SPACE$(dwMsgSize)
        ptrTemp = STRPTR(sTemp)
        ptrBuffer = g_ptrBufferOrig + nCount*dwMsgSize
        FOR i = 0 TO LEN(sTemp) - 1
            IF @ptrBuffer <> 0 THEN @ptrTemp = @ptrBuffer
            INCR ptrBuffer
            INCR ptrTemp
        NEXT
     
        CONTROL SET TEXT g_hDlg, %IDL_MSG, "Read from buffer " + STR$(nCount + 1) + $CrLf + _
                                           TRIM$(sTemp) + $CrLf + $CrLf + _
                                           "# of packages read is " + STR$(g_dwTotalReads)
     
        INCR g_dwTotalReads
        INCR nCount
        IF nCount > dwNumMsgs - 1 THEN nCount = 0
    
        ' Tell sender we are ready to accept data
        ReleaseSemaphore g_hSenderSemaphore, 1, %NULL
     
    END SUB
    '================== END OF READER.BAS =========================================



    [This message has been edited by LRantanen (edited March 06, 2000).]

  • #2
    bugfix

    There was a small but fatal bug, fixed in the code below. It caused the initialisation code to be repeated on every call to read/send data. Eventually Windows (XP, SP3) threw an error, at which time 97,000 handles were in play.

    Code:
    '================== Program READER.BAS ========================================
    #compile exe
    #register none
    #include "Win32Api.Inc"
    
    %PAGE_READWRITE             = &H004
    
    %IDL_MSG                    = 100
    %IDB_CLOSE                  = 101
    
    global g_hDlg               as long
    global g_bDone              as integer
    global g_ptrBufferOrig      as byte ptr
    global g_hSenderSemaphore   as long
    global g_hReaderSemaphore   as long
    global g_dwTotalReads          as dword
    
    declare sub ReadData()
    
    '==============================================================================
    callback function DlgProc
    
        select case cbmsg
    
            case %wm_destroy
                g_bDone = %TRUE
    
            case %wm_command
    
                select case cbwparam
    
                    case %IDB_CLOSE
                        dialog end cbhndl
    
                end select
    
        end select
    
    end function
    
    '==============================================================================
    function pbmain()
    
        local dwResult      as dword
    
        dialog new 0 ,"Reading from Shared Memory", _
                   400, 100, 200, 100, _
                   %ws_sysmenu to g_hDlg
    
        control add label,   g_hDlg, %IDL_MSG, "", _
                             10, 5, 170, 50
    
        control add button,  g_hDlg, %IDB_CLOSE, "Close",  _
                             60, 65, 80, 14
    
        dialog show modeless g_hDlg call DlgProc
    
        while not g_bDone
    
            dialog doevents
    
            ' Has sender sent some data?
            dwResult = WaitForSingleObject(g_hReaderSemaphore, 100)
    
            if dwResult <> %WAIT_TIMEOUT then
                ReadData
            else
                control set text g_hDlg, %IDL_MSG, "Waiting for data"
            end if
    
            if g_bDone <> 0 then exit loop
    
        wend
    
        msgbox "Received totally " + str$(g_dwTotalReads) + " packages"
    
        ' Clean up by closing all handles or at least decrement their refence count
        UnmapViewOfFile g_ptrBufferOrig
        CloseHandle g_hSenderSemaphore
        CloseHandle g_hReaderSemaphore
    
    end function
    
    '==============================================================================
    sub ReadData()
    
        static dwMsgSize             as dword
        static dwNumMsgs             as dword
        static dwBufferSize          as dword
        static szBufferName          as asciiz*%MAX_PATH
        static szSenderSemaphoreName as asciiz*%MAX_PATH
        static szReaderSemaphoreName as asciiz*%MAX_PATH
        static hMemory               as long
        local  dwErrorCode           as dword
    
        static nCount                as integer
        local  sTemp                 as string
        local  ptrTemp               as byte ptr
        local  ptrBuffer             as byte ptr
        local  i                     as integer
        static bInitialized          as integer
    
        if bInitialized = 0 then
            dwMsgSize = 100
            dwNumMsgs = 10
            dwBufferSize = dwNumMsgs * dwMsgSize
            szBufferName = "ShareBufferName"
            szSenderSemaphoreName = "Sender_Semaphore"
            szReaderSemaphoreName = "Reader_Semaphore"
    
            ' Open (or create) semaphore informing sender about the presence and
            ' readiness of the reader process
            g_hSenderSemaphore = CreateSemaphore(byval %NULL, _
                                                 0, _
                                                 1, _
                                                 byval varptr(szSenderSemaphoreName))
    
            dwErrorCode = GetLastError()
            if (g_hSenderSemaphore = %NULL) then
                msgbox "Failed to create " + szSenderSemaphoreName + $crlf + $crlf +_
                       "ERROR " + str$(dwErrorCode)
                exit sub
            end if
    
            ' Semaphore informing reader process about availability of data
            g_hReaderSemaphore = CreateSemaphore(byval %NULL, _
                                                 0, _
                                                 1, _
                                                 byval varptr(szReaderSemaphoreName))
    
            dwErrorCode = GetLastError()
    
            if (g_hReaderSemaphore = %NULL) then
                msgbox "Failed to create " + szReaderSemaphoreName + $crlf + $crlf +_
                       "ERROR " + str$(dwErrorCode)
                CloseHandle g_hSenderSemaphore
                exit sub
            end if
    
            ' Open (or create) a named file mapping backed by swap file
            hMemory = CreateFileMapping(&HFFFFFFFF, _
                                        byval %NULL, _
                                        %PAGE_READWRITE, _
                                        0, _
                                        byval dwBufferSize, _
                                        szBufferName)
    
            dwErrorCode = GetLastError()
            if (hMemory = %NULL) then
                msgbox "Failed to create file mapping for " + szBufferName + $crlf + $crlf +_
                       "ERROR " + str$(dwErrorCode)
                CloseHandle g_hSenderSemaphore
                CloseHandle g_hReaderSemaphore
                exit sub
            end if
    
            ' Create a view of our buffer into the mapping
            ptrBuffer = MapViewOfFile( hMemory, _
                                       %FILE_MAP_WRITE, _
                                       byval 0, _
                                       byval 0, _
                                       byval dwBufferSize)
    
            dwErrorCode = GetLastError()
            if (ptrBuffer = 0) then
                msgbox "Failed to map " + szBufferName + $crlf + $crlf +_
                       "ERROR " + str$(dwErrorCode)
                CloseHandle g_hSenderSemaphore
                CloseHandle g_hReaderSemaphore
                exit sub
            end if
    
            ' Remember where our buffer is
            g_ptrBufferOrig = ptrBuffer
    
            bInitialized = %TRUE
    
        end if
    
        ' Copy sent data intoa string
        sTemp = space$(dwMsgSize)
        ptrTemp = strptr(sTemp)
        ptrBuffer = g_ptrBufferOrig + nCount*dwMsgSize
        for i = 0 to len(sTemp) - 1
            if @ptrBuffer <> 0 then @ptrTemp = @ptrBuffer
            incr ptrBuffer
            incr ptrTemp
        next
    
        control set text g_hDlg, %IDL_MSG, "Read from buffer " + str$(nCount + 1) + $crlf + _
                                           trim$(sTemp) + $crlf + $crlf + _
                                           "# of packages read is " + str$(g_dwTotalReads)
    
        incr g_dwTotalReads
        incr nCount
        if nCount > dwNumMsgs - 1 then nCount = 0
    
        ' Tell sender we are ready to accept data
        ReleaseSemaphore g_hSenderSemaphore, 1, %NULL
    
    end sub
    '================== END OF READER.BAS =========================================
    Code:
    '=================== Program SENDER.BAS ========================================
    #compile exe
    #register none
    #include "Win32Api.Inc"
    
    %PAGE_READWRITE         = &H004
    
    %IDL_MSG                = 100
    %IDB_CLOSE              = 101
    
    global g_hDlg               as long
    global g_bDone              as integer
    global g_ptrBufferOrig      as byte ptr
    global g_hSenderSemaphore   as long
    global g_hReaderSemaphore   as long
    global g_dwTotalSends       as dword
    
    declare sub SendData()
    
    '==============================================================================
    callback function DlgProc
    
        select case cbmsg
    
            case %wm_destroy
                g_bDone = %TRUE
    
            case %wm_command
    
                select case cbwparam
    
                    case %IDB_CLOSE
                        dialog end cbhndl
    
                end select
    
        end select
    
    end function
    
    '==============================================================================
    function pbmain()
    
        local dwResult      as dword
    
        dialog new 0 ,"Writing to Shared Memory", _
                   100, 100, 200, 100, _
                   %ws_sysmenu to g_hDlg
    
        control add label,   g_hDlg, %IDL_MSG, "Waiting for data request", _
                             10, 5, 170, 50
    
        control add button,  g_hDlg, %IDB_CLOSE, "Close",  _
                             60, 65, 80, 14
    
        dialog show modeless g_hDlg call DlgProc
    
        while not g_bDone
            ' Is reader process ready to accept data?
            dwResult = WaitForSingleObject(g_hSenderSemaphore, 100)
    
            if dwResult <> %WAIT_TIMEOUT then
                SendData
            end if
    
            dialog doevents
    
            if g_bDone <> 0 then exit loop
    
        wend
    
        msgbox "Sent totally " + str$(g_dwTotalSends) + " packages"
    
        ' Clean up by closing all handles
        UnmapViewOfFile g_ptrBufferOrig
        CloseHandle g_hSenderSemaphore
        CloseHandle g_hReaderSemaphore
    
    end function
    '==============================================================================
    sub SendData()
    
        static dwMsgSize             as dword
        static dwNumMsgs             as dword
        static dwBufferSize          as dword
        static szBufferName          as asciiz*%MAX_PATH
        static szSenderSemaphoreName as asciiz*%MAX_PATH
        static szReaderSemaphoreName as asciiz*%MAX_PATH
        static hMemory               as long
        local  dwErrorCode           as dword
    
        static nCount                as integer
        local  sTemp                 as string
        local  ptrTemp               as byte ptr
        local  ptrBuffer             as byte ptr
        local  i                     as integer
        static bInitialized          as integer
    
        if bInitialized = 0 then
            dwMsgSize = 100
            dwNumMsgs = 10
            dwBufferSize = dwNumMsgs * dwMsgSize
            szBufferName = "ShareBufferName"
            szSenderSemaphoreName = "Sender_Semaphore"
            szReaderSemaphoreName = "Reader_Semaphore"
    
            ' Create (or open) semaphores thru which processes communicate
            ' Semaphore informing sender about presence of reader process
            ' and its possibility to accept data
            g_hSenderSemaphore = CreateSemaphore(byval %NULL, _
                                                 0, _
                                                 1, _
                                                 byval varptr(szSenderSemaphoreName))
    
            dwErrorCode = GetLastError()
            if (g_hSenderSemaphore = %NULL) then
                msgbox "Failed to create " + szSenderSemaphoreName + $crlf + $crlf +_
                       "ERROR " + str$(dwErrorCode)
                exit sub
            end if
    
            ' Semaphore informing reader process about availability of data
            g_hReaderSemaphore = CreateSemaphore(byval %NULL, _
                                                 0, _
                                                 1, _
                                                 byval varptr(szReaderSemaphoreName))
    
            dwErrorCode = GetLastError()
    
            if (g_hReaderSemaphore = %NULL) then
                msgbox "Failed to create " + szReaderSemaphoreName + $crlf + $crlf +_
                       "ERROR " + str$(dwErrorCode)
                CloseHandle g_hSenderSemaphore
                exit sub
            end if
    
            ' Create a named mapping for our buffer backed up by swap file
            hMemory = CreateFileMapping(&HFFFFFFFF, _
                                        byval %NULL, _
                                        %PAGE_READWRITE, _
                                        0, _
                                        byval dwBufferSize, _
                                        szBufferName)
    
            dwErrorCode = GetLastError()
            if (hMemory = %NULL) then
                msgbox "Failed to create file mapping for " + szBufferName + $crlf + $crlf +_
                       "ERROR " + str$(dwErrorCode)
                CloseHandle g_hSenderSemaphore
                CloseHandle g_hReaderSemaphore
                exit sub
            end if
    
            ' Map our buffer
            ptrBuffer = MapViewOfFile( hMemory, _
                                       %FILE_MAP_WRITE, _
                                       byval 0, _
                                       byval 0, _
                                       byval dwBufferSize)
    
            dwErrorCode = GetLastError()
            if (ptrBuffer = 0) then
                msgbox "Failed to map " + szBufferName + $crlf + $crlf +_
                       "ERROR " + str$(dwErrorCode)
                CloseHandle g_hSenderSemaphore
                CloseHandle g_hReaderSemaphore
                exit sub
            end if
    
            ' Remember where we created the buffer
            g_ptrBufferOrig = ptrBuffer
    
            bInitialized = %TRUE
    
        end if
    
        ' Create message and copy it to the shared memory at next location.
        ' These locations form a ring buffer
        sTemp = "Data #" + str$(nCount+1) + ": " + time$
        ptrTemp = strptr(sTemp)
        ptrBuffer = g_ptrBufferOrig + nCount*dwMsgSize
        for i = 0 to len(sTemp) - 1
            @ptrBuffer = @ptrTemp
            incr ptrBuffer
            incr ptrTemp
        next
    
        incr g_dwTotalSends
    
        control set text g_hDlg, %IDL_MSG, "Sent to buffer #" + str$(nCount + 1) + $crlf + _
                                           sTemp + $crlf+ $crlf + _
                                           "# of packages sent is " + str$(g_dwTotalSends)
        incr nCount
        if nCount > dwNumMsgs - 1 then nCount = 0
    
        ' Tell the reader process that one message has been sent
        ReleaseSemaphore g_hReaderSemaphore, 1, %NULL
    
    end sub
    '================== END OF SENDER.BAS =========================================
    Last edited by Chris Holbrook; 14 Dec 2011, 05:12 AM.

    Comment

    Working...
    X