From 6b911011c04bb5346dd9a88675e991fda0300e0e Mon Sep 17 00:00:00 2001 From: inoussa Date: Fri, 29 Aug 2008 12:57:35 +0000 Subject: [PATCH] OS X compatibility patch, Thanks to Phil for testing. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@537 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- wst/trunk/object_serializer.pas | 42 +++++++++++++-------------------- wst/trunk/wst_delphi_rtl.pas | 37 +++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 26 deletions(-) create mode 100644 wst/trunk/wst_delphi_rtl.pas diff --git a/wst/trunk/object_serializer.pas b/wst/trunk/object_serializer.pas index 72adf5f2a..e936c585f 100644 --- a/wst/trunk/object_serializer.pas +++ b/wst/trunk/object_serializer.pas @@ -16,7 +16,7 @@ unit object_serializer; interface uses - Classes, SysUtils, TypInfo, Contnrs, + Classes, SysUtils, TypInfo, Contnrs, SyncObjs, base_service_intf, wst_types; type @@ -95,9 +95,10 @@ type TBaseComplexTypeRegistryItem = class(TTypeRegistryItem) private - FGetterLock : PtrInt; + FGetterLock : TCriticalSection; FSerializer : TObjectSerializer; FGetFunction : TGetSerializerFunction; + FFuncIsNotReady : Boolean; private function FirstGetter() : TObjectSerializer; function StaticGetter() : TObjectSerializer; @@ -132,13 +133,6 @@ resourcestring SERR_SerializerInitializationException = 'Unable to initialize the serializer of that type : "%s".'; implementation -{$IFDEF WST_DELPHI} - {$IFDEF MSWINDOWS} -uses - Windows; - {$ENDIF MSWINDOWS} -{$ENDIF WST_DELPHI} - procedure ErrorProc( AObject : TObject; @@ -1175,26 +1169,17 @@ end; { TBaseComplexTypeRegistryItem } function TBaseComplexTypeRegistryItem.FirstGetter() : TObjectSerializer; -var - oldValue : PtrInt; begin - if ( InterlockedCompareExchange(Pointer(FGetterLock),Pointer(1),Pointer(0)) = Pointer(0) ) then begin - try + FGetterLock.Acquire(); + try + if ( FSerializer = nil ) then begin FSerializer := TObjectSerializer.Create(TBaseComplexRemotableClass(GetTypeData(DataType)^.ClassType),Owner); - except - InterLockedDecrement(FGetterLock); - raise; + FFuncIsNotReady := True; + FGetFunction := {$IFDEF FPC}@{$ENDIF}StaticGetter; + FFuncIsNotReady := False; end; - FGetFunction := {$IFDEF FPC}@{$ENDIF}StaticGetter; - InterLockedIncrement(FGetterLock); - end else begin - repeat - //this is a way t get the value of "FGetterLock" without altering it. - oldValue := PtrInt(InterlockedCompareExchange(Pointer(FGetterLock),Pointer(1),Pointer(12))); - //this is a busy wait! - until ( oldValue <> 1 ); - if ( oldValue <> 2 ) then - raise ESerializerException.CreateFmt(SERR_SerializerInitializationException,[DataType^.Name]); + finally + FGetterLock.Release(); end; Result := FSerializer; end; @@ -1213,16 +1198,21 @@ constructor TBaseComplexTypeRegistryItem.Create( begin inherited Create(AOwner, ANameSpace, ADataType, ADeclaredName); FGetFunction := {$IFDEF FPC}@{$ENDIF}FirstGetter; + FGetterLock := TCriticalSection.Create(); end; destructor TBaseComplexTypeRegistryItem.Destroy(); begin + FGetterLock.Free(); FSerializer.Free(); inherited Destroy(); end; function TBaseComplexTypeRegistryItem.GetSerializer() : TObjectSerializer; begin + while FFuncIsNotReady do begin + //busy wait + end; Result := FGetFunction(); end; diff --git a/wst/trunk/wst_delphi_rtl.pas b/wst/trunk/wst_delphi_rtl.pas new file mode 100644 index 000000000..26d5f774c --- /dev/null +++ b/wst/trunk/wst_delphi_rtl.pas @@ -0,0 +1,37 @@ +{ + This file is part of the Web Service Toolkit + Copyright (c) 2008 by Inoussa OUEDRAOGO + + This file is provide under modified LGPL licence + ( the files COPYING.modifiedLGPL and COPYING.LGPL). + + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +{$INCLUDE wst_global.inc} +unit wst_delphi_rtl; + +interface +uses + wst_types; + +{$IFDEF WST_DELPHI} + function InterlockedExchange(var Target: Pointer; Value: Pointer): Integer; stdcall; +{$ENDIF WST_DELPHI} + +implementation +{$IFDEF WST_DELPHI} +uses + Windows; +{$ENDIF WST_DELPHI} + +{$IFDEF WST_DELPHI} +function InterlockedExchange(var Target: Pointer; Value: Pointer): Integer; +begin + Windows.InterlockedExchange(PtrInt(Target),PtrInt(Value)); +end; +{$ENDIF WST_DELPHI} + +end. \ No newline at end of file