Skip to content

Commit 53405b6

Browse files
committed
Merge branch 'uck/ThreadSafety' of https://github.com/Kimeek42/AutomaticComponentToolkit into uck/ThreadSafety
2 parents 53693e3 + e5be6e6 commit 53405b6

File tree

3 files changed

+21
-17
lines changed

3 files changed

+21
-17
lines changed

Examples/ThreadSafety/Readme.md

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,13 @@ To address the thread safety issue described above, a new parameter called `thre
2222
This parameter ensures thread safety by adding mutex locking mechanisms on the library implementation side.
2323

2424
### 2.2. Details
25-
The ThreadSafetyOption parameter can be set to either `none`, `soft` or `strict` values. Here is the difference them:
25+
The `ThreadSafetyOption` parameter can be set to `none`, `soft` or `strict` value. Here is the difference between them:
2626
- `none`: Does nothing.
2727
- `soft`: The binding side will call the lock mechanism only when a string is returned from an API function.
2828
- `strict`: The binding side will call the lock mechanism every time, regardless of what is returned from the function.
2929

30-
When the ThreadSafetyOption attribute in the LibraryManager component class is set to `soft` or `strict`,
30+
When the `ThreadSafetyOption` attribute in the component class is set to `soft` or `strict`,
3131
the implementation will derive from a base class that includes mutex locking mechanisms.
32-
This approach ensures that the mutexes are locked and unlocked on the implementation side.
3332
This solution ensures thread safety both when a single pointer on the binding side is shared across threads,
3433
and when different pointers that point to the same object on the implementation side are used in different threads.
3534
Additionally, error handling mechanisms are in place to unlock the mutex in case of exception propagation, preventing deadlocks.
@@ -44,7 +43,7 @@ In the `threadSafeLibrary.xml` file, there are three classes defined with the sa
4443
```xml
4544
<class name="StringReturner" threadsafetyoption="none">
4645
<method name="GetString" description="Returns a string">
47-
<param name="Value" type="string" pass="return"/>
46+
<param name="Value" type="string" pass="return"/>
4847
</method>
4948
<method name="ThreadSafetyCheck" description="Function that may crash when called from different threads at the same time"></method>
5049
</class>
@@ -62,7 +61,7 @@ In the `threadSafeLibrary.xml` file, there are three classes defined with the sa
6261
</class>
6362
```
6463

65-
Each class contains the following methods:
64+
Each class has the following methods:
6665
- `GetString` which simply returns a random string.
6766
- `ThreadSafetyCheck` which returns nothing but may crash when executed from different threads simultaneously, as no thread safety mechanism is provided in the library implementation.
6867

@@ -112,9 +111,9 @@ int main()
112111
}
113112
```
114113
115-
Executing `testStringReturn` and `testThreadSafetyCheck` with `stringReturner` will crash because there is no thread safety mechanism enabled for this instance.
114+
Executing `testStringReturn` and `testThreadSafetyCheck` with `stringReturner` will crash because there is no thread safety mechanism enabled for this instance.
116115
Executing `testStringReturn` with `softStringReturner` will work as expected. However, it will crash on `testThreadSafetyCheck` because with the `soft`
117-
value of the `threadsafetyoption` parameter, the thread safety mechanism will lock the instance on the library side only when executing functions that return strings.
116+
value of the `threadsafetyoption` parameter, the thread safety mechanism will lock the instance on the library side only when executing functions that return strings.
118117
Executing `testStringReturn` or `testThreadSafetyCheck` on `strictStringReturner` will work as expected in both cases because with the `strict` value of
119118
the `threadsafetyoption`, the instance on the implementation side will be locked during each function execution.
120119

Source/automaticcomponenttoolkit.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,13 @@ const (
4848
eACTModeDiff = 1
4949
)
5050

51-
func createComponent(component ComponentDefinition, outfolderBase string, bindingsDirectoryOverride string, interfacesDirectoryOverride string, stubDirectoryOverride string, suppressBindings bool, suppressStub bool, suppressInterfaces bool, suppressSubcomponents bool, suppressLicense bool, suppressExamples bool) (error) {
51+
func createComponent(component ComponentDefinition, outfolderBase string, bindingsDirectoryOverride string, interfacesDirectoryOverride string, stubDirectoryOverride string, suppressBindings bool, suppressStub bool, suppressInterfaces bool, suppressSubcomponents bool, suppressLicense bool, suppressExamples bool, suppressCmake bool) (error) {
5252

5353
log.Printf("Creating Component \"%s\"", component.LibraryName)
5454

5555
if (!suppressSubcomponents) {
5656
for _, subComponent := range component.ImportedComponentDefinitions {
57-
err := createComponent(subComponent, outfolderBase, "", "", "", suppressBindings, suppressStub, suppressInterfaces, suppressSubcomponents, suppressLicense, suppressExamples)
57+
err := createComponent(subComponent, outfolderBase, "", "", "", suppressBindings, suppressStub, suppressInterfaces, suppressSubcomponents, suppressLicense, suppressExamples, suppressCmake)
5858
if (err != nil) {
5959
return err
6060
}
@@ -506,7 +506,7 @@ func createComponent(component ComponentDefinition, outfolderBase string, bindin
506506
}
507507

508508
err = BuildImplementationCPP(component, outputFolderImplementationCpp, outputFolderImplementationCppStub,
509-
outputFolderImplementationProject, implementation, suppressStub, suppressInterfaces)
509+
outputFolderImplementationProject, implementation, suppressStub, suppressInterfaces, suppressCmake)
510510
if err != nil {
511511
return err
512512
}
@@ -578,6 +578,7 @@ func printUsageInfo() {
578578
fmt.Fprintln(os.Stdout, " -suppressinterfaces: do not generate the contents of the interfaces-folder")
579579
fmt.Fprintln(os.Stdout, " -suppresssubcomponents: do not generate any files for subcomponents")
580580
fmt.Fprintln(os.Stdout, " -suppressexamples: do not generate any examples")
581+
fmt.Fprintln(os.Stdout, " -suppresscmake: do not generate CMakeLists.txt file for C++ implementation. It only takes effect if -suppressstub argument is not set.")
581582
fmt.Fprintln(os.Stdout, " ")
582583
fmt.Fprintln(os.Stdout, "Tutorials, info and source-code on: https://github.com/Autodesk/AutomaticComponentToolkit/ .")
583584
fmt.Fprintln(os.Stdout, "ACT stops now.")
@@ -616,6 +617,7 @@ func main() {
616617
suppressInterfaces := false;
617618
suppressSubcomponents := false;
618619
suppressExamples := false;
620+
suppressCmake := false;
619621

620622
if len(os.Args) >= 4 {
621623
for idx := 2; idx < len(os.Args); idx ++ {
@@ -667,6 +669,9 @@ func main() {
667669
suppressExamples = true;
668670
}
669671

672+
if os.Args[idx] == "-suppresscmake" {
673+
suppressCmake = true;
674+
}
670675
}
671676
}
672677
if mode == eACTModeGenerate {
@@ -735,7 +740,7 @@ func main() {
735740
// }
736741
// }
737742

738-
err = createComponent(component, outfolderBase, bindingsDirectoryOverride, interfacesDirectoryOverride, stubDirectoryOverride, suppressBindings, suppressStub, suppressInterfaces, suppressSubcomponents, suppressLicense, suppressExamples)
743+
err = createComponent(component, outfolderBase, bindingsDirectoryOverride, interfacesDirectoryOverride, stubDirectoryOverride, suppressBindings, suppressStub, suppressInterfaces, suppressSubcomponents, suppressLicense, suppressExamples, suppressCmake)
739744
if (err != nil) {
740745
if err == ErrPythonBuildFailed {
741746
log.Println("Python binding generation failed (Due to usage of reserved keywords)")

Source/buildimplementationcpp.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ import (
4343
)
4444

4545
// BuildImplementationCPP builds C++ interface classes, implementation stubs and wrapper code that maps to the C-header
46-
func BuildImplementationCPP(component ComponentDefinition, outputFolder string, stubOutputFolder string, projectOutputFolder string, implementation ComponentDefinitionImplementation, suppressStub bool, suppressInterfaces bool) error {
46+
func BuildImplementationCPP(component ComponentDefinition, outputFolder string, stubOutputFolder string, projectOutputFolder string, implementation ComponentDefinitionImplementation, suppressStub bool, suppressInterfaces bool, suppressCmake bool) error {
4747
forceRecreation := false
4848

4949
doJournal := len (component.Global.JournalMethod) > 0;
@@ -169,7 +169,7 @@ func BuildImplementationCPP(component ComponentDefinition, outputFolder string,
169169
log.Printf("Omitting recreation of implementation stub \"%s\"", IntfWrapperStubName)
170170
}
171171

172-
if ( len(projectOutputFolder) > 0 ) {
172+
if ( !suppressCmake && len(projectOutputFolder) > 0 ) {
173173
CMakeListsFileName := path.Join(projectOutputFolder, "CMakeLists.txt");
174174
if forceRecreation || !FileExists(CMakeListsFileName) {
175175
log.Printf("Creating CMake-Project \"%s\" for CPP Implementation", CMakeListsFileName)
@@ -833,11 +833,11 @@ func buildCPPGetSymbolAddressMethod(component ComponentDefinition, w LanguageWri
833833
}
834834

835835
func buildCPPInterfaceWrapper(component ComponentDefinition, w LanguageWriter, NameSpace string, NameSpaceImplementation string, ClassIdentifier string, BaseName string, doJournal bool) error {
836-
w.Writeln("#include \"%s_abi.hpp\"", strings.ToLower(BaseName))
837-
w.Writeln("#include \"%s_interfaces.hpp\"", strings.ToLower(BaseName))
838-
w.Writeln("#include \"%s_interfaceexception.hpp\"", strings.ToLower(BaseName))
836+
w.Writeln("#include \"%s_abi.hpp\"", BaseName)
837+
w.Writeln("#include \"%s_interfaces.hpp\"", BaseName)
838+
w.Writeln("#include \"%s_interfaceexception.hpp\"", BaseName)
839839
if (doJournal) {
840-
w.Writeln("#include \"%s_interfacejournal.hpp\"", strings.ToLower(BaseName))
840+
w.Writeln("#include \"%s_interfacejournal.hpp\"", BaseName)
841841
}
842842
w.Writeln("")
843843
w.Writeln("#include <map>")

0 commit comments

Comments
 (0)