@@ -591,7 +591,7 @@ func writeDynamicCPPMethodDeclaration(method ComponentDefinitionMethod, w Langua
591
591
}
592
592
593
593
func writeDynamicCPPMethod (method ComponentDefinitionMethod , w LanguageWriter , NameSpace string , ClassIdentifier string , ClassName string ,
594
- implementationLines []string , isGlobal bool , includeComments bool , doNotThrow bool , useCPPTypes bool , ExplicitLinking bool , forWASM bool ) error {
594
+ implementationLines []string , isGlobal bool , includeComments bool , doNotThrow bool , useCPPTypes bool , ExplicitLinking bool , forWASM bool , multiThreadedEnv bool , classThreadSafetyOption ThreadSafetyOption ) error {
595
595
596
596
WASMPrefix := ""
597
597
WASMCast := ""
@@ -616,6 +616,14 @@ func writeDynamicCPPMethod(method ComponentDefinitionMethod, w LanguageWriter, N
616
616
checkErrorCodeEnd := ")"
617
617
makeSharedParameter := ""
618
618
619
+ if multiThreadedEnv && ! isGlobal {
620
+ if classThreadSafetyOption == eThreadSafetyStrict {
621
+ checkErrorCodeEnd = ", true)"
622
+ } else {
623
+ checkErrorCodeEnd = ", false)"
624
+ }
625
+ }
626
+
619
627
if isGlobal {
620
628
if ExplicitLinking {
621
629
CMethodName = fmt .Sprintf ("m_WrapperTable.m_%s" , method .MethodName )
@@ -858,6 +866,12 @@ func writeDynamicCPPMethod(method ComponentDefinitionMethod, w LanguageWriter, N
858
866
initCallParameters = initCallParameters + initCallParameter
859
867
}
860
868
869
+ addThreadSafeCalls := multiThreadedEnv && ! isGlobal && ((classThreadSafetyOption == eThreadSafetySoft && requiresInitCall ) || classThreadSafetyOption == eThreadSafetyStrict )
870
+
871
+ if addThreadSafeCalls {
872
+ checkErrorCodeEnd = ", true)"
873
+ }
874
+
861
875
w .Writeln (" " )
862
876
if includeComments {
863
877
w .Writeln (" /**" )
@@ -876,6 +890,11 @@ func writeDynamicCPPMethod(method ComponentDefinitionMethod, w LanguageWriter, N
876
890
877
891
w .Writeln (" {" )
878
892
w .Writelns (" " , definitionCodeLines )
893
+
894
+ if addThreadSafeCalls {
895
+ w .Writeln (" %s();" , getLockInstanceMethodName ())
896
+ }
897
+
879
898
if requiresInitCall {
880
899
w .Writeln (" %s%s(%s)%s;" , checkErrorCodeBegin , CMethodName , initCallParameters , checkErrorCodeEnd )
881
900
}
@@ -888,6 +907,10 @@ func writeDynamicCPPMethod(method ComponentDefinitionMethod, w LanguageWriter, N
888
907
w .Writelns (" " , implementationLines )
889
908
}
890
909
910
+ if addThreadSafeCalls {
911
+ w .Writeln (" %s();" , getUnlockInstanceMethodName ())
912
+ }
913
+
891
914
if len (returnCodeLines ) > 0 {
892
915
w .Writeln (" " )
893
916
w .Writelns (" " , returnCodeLines )
@@ -905,11 +928,20 @@ func writeDynamicCppBaseClassMethods(component ComponentDefinition, baseClass Co
905
928
w .Writeln (" /* Handle to Instance in library*/" )
906
929
w .Writeln (" %sHandle m_pHandle;" , NameSpace )
907
930
w .Writeln ("" )
908
- w .Writeln (" /* Checks for an Error code and raises Exceptions */" )
909
- w .Writeln (" void CheckError(%sResult nResult)" , NameSpace )
931
+ if component .isMultiThreadedEnv () {
932
+ w .Writeln (" /* Checks for an Error code, raises Exceptions and unlocks library object*/" )
933
+ w .Writeln (" void CheckError(%sResult nResult, bool unlockIfError)" , NameSpace )
934
+ } else {
935
+ w .Writeln (" /* Checks for an Error code and raises Exceptions */" )
936
+ w .Writeln (" void CheckError(%sResult nResult)" , NameSpace )
937
+ }
910
938
w .Writeln (" {" )
911
939
w .Writeln (" if (m_pWrapper != nullptr)" )
912
- w .Writeln (" m_pWrapper->CheckError(this, nResult);" )
940
+ if component .isMultiThreadedEnv () {
941
+ w .Writeln (" m_pWrapper->CheckError(this, nResult, unlockIfError);" )
942
+ } else {
943
+ w .Writeln (" m_pWrapper->CheckError(this, nResult);" )
944
+ }
913
945
w .Writeln (" }" )
914
946
w .Writeln ("public:" )
915
947
w .Writeln (" /**" )
@@ -1390,19 +1422,42 @@ func writeClassDeclarations(w LanguageWriter, component ComponentDefinition, cpp
1390
1422
w .Writeln (" {" )
1391
1423
w .Writeln (" }" )
1392
1424
w .Writeln (" " )
1425
+
1426
+ for _ , method := range class .Methods {
1427
+ err := writeDynamicCPPMethodDeclaration (method , w , NameSpace , ClassIdentifier , cppClassName )
1428
+ if err != nil {
1429
+ return err
1430
+ }
1431
+ }
1432
+
1393
1433
} else {
1394
1434
err := writeDynamicCppBaseClassMethods (component , baseClass , w , NameSpace , BaseName , cppClassPrefix , ClassIdentifier )
1395
1435
if err != nil {
1396
1436
return err
1397
1437
}
1398
- }
1399
1438
1400
- for _ , method := range class .Methods {
1401
- err := writeDynamicCPPMethodDeclaration (method , w , NameSpace , ClassIdentifier , cppClassName )
1402
- if err != nil {
1403
- return err
1439
+ extraBaseClassMethods := []ComponentDefinitionMethod {}
1440
+ for _ , method := range class .Methods {
1441
+ if method .isExtraBaseClassmethod () {
1442
+ extraBaseClassMethods = append (extraBaseClassMethods , method )
1443
+ } else {
1444
+ err := writeDynamicCPPMethodDeclaration (method , w , NameSpace , ClassIdentifier , cppClassName )
1445
+ if err != nil {
1446
+ return err
1447
+ }
1448
+ }
1449
+ }
1450
+
1451
+ w .Writeln (" " )
1452
+ w .Writeln ("protected:" )
1453
+ for _ , method := range extraBaseClassMethods {
1454
+ err := writeDynamicCPPMethodDeclaration (method , w , NameSpace , ClassIdentifier , cppClassName )
1455
+ if err != nil {
1456
+ return err
1457
+ }
1404
1458
}
1405
1459
}
1460
+
1406
1461
w .Writeln ("};" )
1407
1462
}
1408
1463
return nil
@@ -1450,13 +1505,22 @@ func writePolymorphicFactoryImplementation(w LanguageWriter, component Component
1450
1505
w .Writeln ("}" )
1451
1506
}
1452
1507
1453
- func writeCheckErrorImplementation (w LanguageWriter , ErrorMethodName string , ClassIdentifier string , cppBaseClassName string , NameSpace string ) {
1454
- w .Writeln (" inline void C%sWrapper::CheckError(%s * pBaseClass, %sResult nResult)" , ClassIdentifier , cppBaseClassName , NameSpace )
1508
+ func writeCheckErrorImplementation (w LanguageWriter , ErrorMethodName string , ClassIdentifier string , cppBaseClassName string , NameSpace string , multiThreadedEnv bool ) {
1509
+ if multiThreadedEnv {
1510
+ w .Writeln (" inline void C%sWrapper::CheckError(%s * pBaseClass, %sResult nResult, bool unlockIfError)" , ClassIdentifier , cppBaseClassName , NameSpace )
1511
+ } else {
1512
+ w .Writeln (" inline void C%sWrapper::CheckError(%s * pBaseClass, %sResult nResult)" , ClassIdentifier , cppBaseClassName , NameSpace )
1513
+ }
1455
1514
w .Writeln (" {" )
1456
1515
w .Writeln (" if (nResult != 0) {" )
1457
1516
w .Writeln (" std::string sErrorMessage;" )
1458
1517
w .Writeln (" if (pBaseClass != nullptr) {" )
1459
1518
w .Writeln (" %s(pBaseClass, sErrorMessage);" , ErrorMethodName )
1519
+ if multiThreadedEnv {
1520
+ w .Writeln (" if (unlockIfError) {" )
1521
+ w .Writeln (" pBaseClass->%s();" , getUnlockInstanceMethodName ())
1522
+ w .Writeln (" }" )
1523
+ }
1460
1524
w .Writeln (" }" )
1461
1525
w .Writeln (" throw E%sException(nResult, sErrorMessage);" , NameSpace )
1462
1526
w .Writeln (" }" )
@@ -1539,7 +1603,11 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s
1539
1603
writeWrapperLifeTimeHandling (w , cppClassPrefix , ClassIdentifier , ExplicitLinking )
1540
1604
1541
1605
w .Writeln (" " )
1542
- w .Writeln (" inline void CheckError(%s * pBaseClass, %sResult nResult);" , cppBaseClassName , NameSpace )
1606
+ if component .isMultiThreadedEnv () {
1607
+ w .Writeln (" inline void CheckError(%s * pBaseClass, %sResult nResult, bool unlockIfError = false);" , cppBaseClassName , NameSpace )
1608
+ } else {
1609
+ w .Writeln (" inline void CheckError(%s * pBaseClass, %sResult nResult);" , cppBaseClassName , NameSpace )
1610
+ }
1543
1611
w .Writeln ("" )
1544
1612
1545
1613
for j := 0 ; j < len (global .Methods ); j ++ {
@@ -1622,15 +1690,15 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s
1622
1690
implementationLines = append (implementationLines , fmt .Sprintf (" throw E%sException(%s_ERROR_COULDNOTLOADLIBRARY, \" Unknown namespace \" + %s);" , NameSpace , strings .ToUpper (NameSpace ), sParamName ))
1623
1691
}
1624
1692
1625
- err = writeDynamicCPPMethod (method , w , NameSpace , ClassIdentifier , "Wrapper" , implementationLines , true , true , false , useCPPTypes , ExplicitLinking , false )
1693
+ err = writeDynamicCPPMethod (method , w , NameSpace , ClassIdentifier , "Wrapper" , implementationLines , true , true , false , useCPPTypes , ExplicitLinking , false , component . isMultiThreadedEnv (), eThreadSafetyNone )
1626
1694
if err != nil {
1627
1695
return err
1628
1696
}
1629
1697
1630
1698
}
1631
1699
1632
1700
w .Writeln ("" )
1633
- writeCheckErrorImplementation (w , component .Global .ErrorMethod , ClassIdentifier , cppBaseClassName , NameSpace )
1701
+ writeCheckErrorImplementation (w , component .Global .ErrorMethod , ClassIdentifier , cppBaseClassName , NameSpace , component . isMultiThreadedEnv () )
1634
1702
w .Writeln ("" )
1635
1703
1636
1704
if ExplicitLinking {
@@ -1648,7 +1716,7 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s
1648
1716
w .Writeln (" */" )
1649
1717
for j := 0 ; j < len (class .Methods ); j ++ {
1650
1718
method := class .Methods [j ]
1651
- err := writeDynamicCPPMethod (method , w , NameSpace , ClassIdentifier , class .ClassName , make ([]string , 0 ), false , true , false , useCPPTypes , ExplicitLinking , false )
1719
+ err := writeDynamicCPPMethod (method , w , NameSpace , ClassIdentifier , class .ClassName , make ([]string , 0 ), false , true , false , useCPPTypes , ExplicitLinking , false , component . isMultiThreadedEnv (), class . eThreadSafetyOption () )
1652
1720
if err != nil {
1653
1721
return err
1654
1722
}
@@ -2217,14 +2285,14 @@ func buildCppwasmGuestHeader(component ComponentDefinition, w LanguageWriter, Na
2217
2285
implementationLines = append (implementationLines , fmt .Sprintf (" throw E%sException(%s_ERROR_COULDNOTLOADLIBRARY, \" Unknown namespace \" + %s);" , NameSpace , strings .ToUpper (NameSpace ), sParamName ))
2218
2286
}
2219
2287
2220
- err = writeDynamicCPPMethod (method , w , NameSpace , ClassIdentifier , "Wrapper" , implementationLines , true , true , false , useCPPTypes , ExplicitLinking , true )
2288
+ err = writeDynamicCPPMethod (method , w , NameSpace , ClassIdentifier , "Wrapper" , implementationLines , true , true , false , useCPPTypes , ExplicitLinking , true , false , eThreadSafetyNone )
2221
2289
if err != nil {
2222
2290
return err
2223
2291
}
2224
2292
}
2225
2293
2226
2294
w .Writeln ("" )
2227
- writeCheckErrorImplementation (w , component .Global .ErrorMethod , ClassIdentifier , cppBaseClassName , NameSpace )
2295
+ writeCheckErrorImplementation (w , component .Global .ErrorMethod , ClassIdentifier , cppBaseClassName , NameSpace , false )
2228
2296
w .Writeln ("" )
2229
2297
2230
2298
for i := 0 ; i < len (component .Classes ); i ++ {
@@ -2236,7 +2304,7 @@ func buildCppwasmGuestHeader(component ComponentDefinition, w LanguageWriter, Na
2236
2304
w .Writeln (" */" )
2237
2305
for j := 0 ; j < len (class .Methods ); j ++ {
2238
2306
method := class .Methods [j ]
2239
- err := writeDynamicCPPMethod (method , w , NameSpace , ClassIdentifier , class .ClassName , make ([]string , 0 ), false , true , false , useCPPTypes , ExplicitLinking , true )
2307
+ err := writeDynamicCPPMethod (method , w , NameSpace , ClassIdentifier , class .ClassName , make ([]string , 0 ), false , true , false , useCPPTypes , ExplicitLinking , true , false , eThreadSafetyNone )
2240
2308
if err != nil {
2241
2309
return err
2242
2310
}
0 commit comments