@@ -35,26 +35,42 @@ public class Client {
3535 * Reference to the default client instance with type coercion enabled
3636 * for both inputs and outputs.
3737 */
38- private static Client instance ;
38+ private static volatile Client instance ;
39+
40+ private Client (boolean coerceInputs , boolean coerceOutputs ) {
41+ this .coerceInputs = coerceInputs ;
42+ this .coerceOutputs = coerceOutputs ;
43+ }
44+
45+ private Client () {
46+ this (true , true );
47+ }
3948
4049 /**
4150 * Retrieves the global reference to a client that has both input coercion
4251 * and output coercion enabled.
4352 *
4453 * @return Singleton instance.
4554 */
46- public static Client getInstance (){
47- if ( instance == null ){
48- instance = new Client ();
55+ public static Client getInstance () {
56+ Client localInstance = instance ;
57+ if (localInstance == null ) {
58+ // Could also use dedicated lock for `instance` and `rawClient`, but likely not worth it
59+ synchronized (Client .class ) {
60+ localInstance = instance ;
61+ if (localInstance == null ) {
62+ instance = localInstance = new Client ();
63+ }
64+ }
4965 }
50- return instance ;
66+ return localInstance ;
5167 }
5268
5369 /**
5470 * Reference to a simple client that has type coercion disabled for both
5571 * inputs and outputs.
5672 */
57- private static Client rawClient ;
73+ private static volatile Client rawClient ;
5874
5975 /**
6076 * Retrieves singleton instance to a simple client that has type coercion
@@ -63,12 +79,19 @@ public static Client getInstance(){
6379 * @return a {@link ca.weblite.objc.Client} object.
6480 */
6581 public static Client getRawClient (){
66- if ( rawClient == null ){
67- rawClient = new Client ();
68- rawClient .coerceInputs = false ;
69- rawClient .coerceOutputs = false ;
82+ Client localInstance = rawClient ;
83+
84+ if (localInstance == null ){
85+ synchronized (Client .class ) {
86+ localInstance = rawClient ;
87+ if (localInstance == null ) {
88+ localInstance = new Client (false , false );
89+ rawClient = localInstance ;
90+ }
91+ }
92+
7093 }
71- return rawClient ;
94+ return localInstance ;
7295 }
7396
7497 /**
@@ -78,30 +101,32 @@ public static Client getRawClient(){
78101 * TypeMapping subclasses.
79102 *
80103 */
81- boolean coerceInputs = true ;
104+ final boolean coerceInputs ;
82105
83106 /**
84107 * Flag to indicate whether the output of messages should be coerced. If
85108 * this flag is true, then any C outputs from messages will be converted
86109 * to their corresponding Java types using the TypeMapper class.
87110 */
88- boolean coerceOutputs = true ;
111+ final boolean coerceOutputs ;
89112
90113
91114
92115 /**
93116 * Set the coerceInputs flag. Setting this to true will cause all subsequent
94117 * requests to coerce the input (i.e. convert Java parameters to corresponding
95118 * C-types).
119+ *
96120 *
97121 * @param coerceInputs Whether to coerce inputs to messages.
98122 * @return Self for chaining.
99123 * @see TypeMapper
100124 * @see TypeMapping
125+ * @Deprecated Use {@link #getRawClient() } to get a client with coercion off. Use {@link #getInstance() } to get a client with coercion on.
101126 */
102127 public Client setCoerceInputs (boolean coerceInputs ){
103- this . coerceInputs = coerceInputs ;
104- return this ;
128+ throw new UnsupportedOperationException ( "Cannot modify coerce inputs setting on shared global instance of Objective-C client" ) ;
129+
105130 }
106131
107132 /**
@@ -113,10 +138,10 @@ public Client setCoerceInputs(boolean coerceInputs){
113138 * @return Self for chaining.
114139 * @see TypeMapper
115140 * @see TypeMapping
141+ * @Deprecated Use {@link #getRawClient() } to get a client with coercion off. Use {@link #getInstance() } to get a client with coercion on.
116142 */
117143 public Client setCoerceOutputs (boolean coerceOutputs ){
118- this .coerceOutputs = coerceOutputs ;
119- return this ;
144+ throw new UnsupportedOperationException ("Cannot modify coerce inputs setting on shared global instance of Objective-C client" );
120145 }
121146
122147
0 commit comments