diff --git a/src/ThreadedFFI-UFFI-Tests/TFUFFIConcurrencyTest.class.st b/src/ThreadedFFI-UFFI-Tests/TFUFFIConcurrencyTest.class.st new file mode 100644 index 00000000000..51a36e61b66 --- /dev/null +++ b/src/ThreadedFFI-UFFI-Tests/TFUFFIConcurrencyTest.class.st @@ -0,0 +1,80 @@ +Class { + #name : #TFUFFIConcurrencyTest, + #superclass : #TFUFFITestCase, + #instVars : [ + 'p1', + 'p2' + ], + #category : #'ThreadedFFI-UFFI-Tests' +} + +{ #category : #'ffi-calls' } +TFUFFIConcurrencyTest >> booleanToInt: boolean [ + + ^ self ffiCall: #(int id_int(Boolean boolean)) +] + +{ #category : #'ffi-calls' } +TFUFFIConcurrencyTest >> methodCallingBooleanToInt [ + + ^ self booleanToInt: true +] + +{ #category : #running } +TFUFFIConcurrencyTest >> tearDown [ + + FFIMethodRegistry uniqueInstance resetSingleClass: self class. + + p1 ifNotNil: #terminate. + p2 ifNotNil: #terminate. + + (self class >> #booleanToInt: hasProperty: #ffiNonCompiledMethod) + ifTrue: [ + self class compile: ' +booleanToInt: boolean + + ^ self ffiCall: #(int id_int(Boolean boolean)) ' ]. + super tearDown +] + +{ #category : #tests } +TFUFFIConcurrencyTest >> testConcurrentlyCompiling [ + + | barrier finish installedMethod nonCompiledMethod | + self deny: + (self class >> #booleanToInt: hasProperty: #ffiNonCompiledMethod). + + barrier := Semaphore new. + finish := Semaphore new. + + + p1 := [ + [ + barrier wait. + self methodCallingBooleanToInt. + finish signal ] repeat ] forkAt: 39. + + p2 := [ + [ + barrier wait. + self methodCallingBooleanToInt. + finish signal ] repeat ] forkAt: 39. + + 500 timesRepeat: [ + + FFIMethodRegistry uniqueInstance resetSingleClass: self class. + + barrier + signal; + signal. + finish + wait; + wait. + + installedMethod := self class >> #booleanToInt:. + nonCompiledMethod := installedMethod propertyAt: + #ffiNonCompiledMethod. + + self assert: (installedMethod hasProperty: #ffiNonCompiledMethod). + self deny: (nonCompiledMethod hasProperty: #ffiNonCompiledMethod) ] +] diff --git a/src/UnifiedFFI/FFICalloutAPI.class.st b/src/UnifiedFFI/FFICalloutAPI.class.st index fdde299f456..be02fc57ab1 100644 --- a/src/UnifiedFFI/FFICalloutAPI.class.st +++ b/src/UnifiedFFI/FFICalloutAPI.class.st @@ -125,7 +125,7 @@ FFICalloutAPI >> function: functionSignature library: moduleNameOrLibrary [ methodClass: sender methodClass. "Replace with generated ffi method, but save old one for future use" ffiMethod propertyAt: #ffiNonCompiledMethod - put: (sender methodClass methodDict at: sender selector). "For senders search, one need to keep the selector in the properties" + put: sender method. "For senders search, one need to keep the selector in the properties" ffiMethod propertyAt: #ffiMethodSelector put: ffiMethodSelector. sender methodClass methodDict at: sender selector put: ffiMethod. "Register current method as compiled for ffi" FFIMethodRegistry uniqueInstance registerMethod: ffiMethod. "Resend"