*_______________________________________________________________________________ #define true .t. #define false .f. #include "FoxPro.h" function Do_it() ?TryLogOn() && Start of App endfunc *_______________________________________________________________________________ function TryLogon() local success success = true local obj, semaphoreName, maxCount, isGlobal semaphoreName = 'MyApplicationName' isGlobal = TSE_Session() maxCount = 10 && max simultaneous users do case case !m.success case !Semaphore_Object(@m.obj, m.semaphoreName, m.maxCount, m.isGlobal) assert false success = false case !m.obj.TryDecrement(0) && ms to wait assert false success = false case !_screen.AddProperty('MyLogonCountObject', m.obj) assert false success = false otherwise && MyLogonCountObject will be destroyed on app exit and the count reset endcase return m.success endfunc *_______________________________________________________________________________ *_______________________________________________________________________________ function Semaphore_Object(obj, semaphoreName, maxCount, isGlobal) local success success = true obj = null try obj = createObject('Semaphore', m.semaphoreName, m.maxCount, m.isGlobal) catch assert false success = false endtry return m.success and inlist(vartype(m.obj), T_OBJECT) endfunc *_______________________________________________________________________________ *=============================================================================== *=============================================================================== *=============================================================================== define class Semaphore as Relation SemaphoreHandle = 0 OpenCount = 0 *_______________________________________________________________________________ protected function init(semaphoreName, maxCount, isGlobal) local success success = true do case case !m.success case !DoDefault() assert false success = false case !m.this.CreateSemaphore(m.semaphoreName, m.maxCount, m.isGlobal) assert false success = false endcase return m.success endfunc *_______________________________________________________________________________ protected function CreateSemaphore(semaphoreName, maxCount, isGlobal) local success success = true do case case !m.success case !m.this.IsChar(m.semaphoreName, true) assert false success = false case !m.this.IsPositiveInteger(m.maxCount) assert false success = false case !m.this.IsLogical(m.isGlobal) assert false success = false case '\' $ m.semaphoreName assert false success = false error 11, 'semaphoreName' otherwise this.SemaphoreHandle = CreateSemaphore( ; null, ; m.maxCount, ; m.maxCount, ; iif(m.isGlobal, 'Global\', 'Local\') + m.semaphoreName ; ) endcase do case case !m.success case empty(m.this.SemaphoreHandle) assert false success = false endcase return m.success endfunc *_______________________________________________________________________________ protected function Destroy() do case case empty(m.this.SemaphoreHandle) otherwise do while !empty(m.this.OpenCount) and m.this.TryIncrement() enddo =CloseHandle(m.this.SemaphoreHandle) endcase return DoDefault() endfunc *_______________________________________________________________________________ #define WAIT_ABANDONED 0x00000080 #define WAIT_OBJECT_0 0x00000000 #define WAIT_TIMEOUT 0x00000102 #define WAIT_FAILED bitor(0xFFFFFFFF, 0) function TryDecrement(msTimeOut) local success success = true do case case !m.success case !m.this.IsNonNegativeInteger(m.msTimeOut) assert false success = false otherwise v = WaitForSingleObject(m.this.SemaphoreHandle, m.msTimeOut) do case case inlist(m.v, WAIT_ABANDONED, WAIT_FAILED) assert false success = false case inlist(m.v, WAIT_TIMEOUT) success = false case inlist(m.v, WAIT_OBJECT_0) this.OpenCount = m.this.OpenCount + 1 otherwise assert false && program error endcase endcase return m.success endfunc *_______________________________________________________________________________ protected function TryIncrement() local success success = true local lpPreviousCount lpPreviousCount = 0 do case case !m.success case empty(m.this.OpenCount) assert false success = false case empty(ReleaseSemaphore( ; m.this.SemaphoreHandle, ; 1, ; @m.lpPreviousCount ; ) ; ) assert false success = false otherwise this.OpenCount = m.this.OpenCount - 1 endcase return m.success endfunc *_______________________________________________________________________________ protected function IsChar(s, needFilled) return inlist(vartype(m.s), T_CHARACTER, T_MEMO) ; and iif(m.needFilled, !empty(len(m.s)), true) endfunc *_______________________________________________________________________________ protected function IsLogical(s) return inlist(vartype(m.s), T_LOGICAL) endfunc *_______________________________________________________________________________ protected function IsNumeric(s) return inlist(vartype(m.s), T_NUMERIC, T_DOUBLE, T_FLOAT, T_INTEGER) endfunc *_______________________________________________________________________________ protected function IsInteger(s) return m.this.IsNumeric(m.s) and empty(mod(m.s, 1)) endfunc *_______________________________________________________________________________ protected function IsPositiveInteger(s) return m.this.IsInteger(m.s) and ( m.s > 0 ) endfunc *_______________________________________________________________________________ protected function IsNonNegativeInteger(s) return m.this.IsInteger(m.s) and ( m.s >= 0 ) endfunc *_______________________________________________________________________________ enddefine *=============================================================================== *=============================================================================== *=============================================================================== *_______________________________________________________________________________ function CloseHandle(handle) local returnvalue try declare integer CloseHandle in Kernel32.dll ; long handle returnvalue = CloseHandle(m.handle) catch assert false returnvalue = false endtry return m.returnvalue endfunc *_______________________________________________________________________________ function WaitForSingleObject(handle, dwMilliseconds) local returnvalue try declare integer WaitForSingleObject in Kernel32.dll ; long handle, ; long dwMilliseconds returnvalue = WaitForSingleObject(m.handle, m.dwMilliseconds) catch assert false returnvalue = false endtry return m.returnvalue endfunc *_______________________________________________________________________________ function CreateSemaphore lparameters lpSemaphoreAttributes, ; lInitialCount, ; lMaximumCount, ; lpName local returnvalue try declare integer CreateSemaphore in Kernel32.dll ; string lpSemaphoreAttributes, ; long lInitialCount, ; long lMaximumCount, ; string lpName returnvalue = CreateSemaphore( ; m.lpSemaphoreAttributes, ; m.lInitialCount, ; m.lMaximumCount, ; m.lpName ; ) catch assert false returnvalue = false endtry return m.returnvalue endfunc *_______________________________________________________________________________ function ReleaseSemaphore lparameters hSemaphore, ; lReleaseCount, ; lpPreviousCount local returnvalue try declare integer ReleaseSemaphore in Kernel32.dll ; long hSemaphore, ; long lReleaseCount, ; long @lpPreviousCount returnvalue = ReleaseSemaphore( ; m.hSemaphore, ; m.lReleaseCount, ; @m.lpPreviousCount ; ) catch assert false returnvalue = false endtry return m.returnvalue endfunc *_______________________________________________________________________________