rb-scpt 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/bin/rb-scpt-1.0.1.gem +0 -0
  3. data/extconf.rb +12 -12
  4. data/rb-scpt.gemspec +10 -10
  5. data/sample/AB_export_vcard.rb +16 -16
  6. data/sample/AB_list_people_with_emails.rb +4 -4
  7. data/sample/Add_iCal_event.rb +12 -12
  8. data/sample/Create_daily_iCal_todos.rb +28 -28
  9. data/sample/Export_Address_Book_phone_numbers.rb +52 -52
  10. data/sample/Hello_world.rb +10 -10
  11. data/sample/List_iTunes_playlist_names.rb +3 -3
  12. data/sample/Make_Mail_message.rb +24 -24
  13. data/sample/Open_file_in_TextEdit.rb +5 -5
  14. data/sample/Organize_Mail_messages.rb +46 -46
  15. data/sample/Print_folder_tree.rb +5 -5
  16. data/sample/Select_all_HTML_files.rb +6 -6
  17. data/sample/Set_iChat_status.rb +12 -12
  18. data/sample/Simple_Finder_GUI_Scripting.rb +6 -6
  19. data/sample/Stagger_Finder_windows.rb +9 -9
  20. data/sample/TextEdit_demo.rb +71 -71
  21. data/sample/iTunes_top40_to_html.rb +28 -30
  22. data/src/SendThreadSafe.c +293 -293
  23. data/src/SendThreadSafe.h +108 -108
  24. data/src/lib/_aem/aemreference.rb +997 -998
  25. data/src/lib/_aem/codecs.rb +609 -610
  26. data/src/lib/_aem/connect.rb +197 -197
  27. data/src/lib/_aem/encodingsupport.rb +67 -67
  28. data/src/lib/_aem/findapp.rb +75 -75
  29. data/src/lib/_aem/mactypes.rb +241 -242
  30. data/src/lib/_aem/send.rb +268 -268
  31. data/src/lib/_aem/typewrappers.rb +52 -52
  32. data/src/lib/_appscript/defaultterminology.rb +266 -266
  33. data/src/lib/_appscript/referencerenderer.rb +230 -233
  34. data/src/lib/_appscript/reservedkeywords.rb +106 -106
  35. data/src/lib/_appscript/safeobject.rb +125 -125
  36. data/src/lib/_appscript/terminology.rb +448 -449
  37. data/src/lib/aem.rb +238 -238
  38. data/src/lib/kae.rb +1487 -1487
  39. data/src/lib/osax.rb +647 -647
  40. data/src/lib/rb-scpt.rb +1065 -1065
  41. data/src/rbae.c +595 -595
  42. data/test/test_aemreference.rb +104 -107
  43. data/test/test_appscriptcommands.rb +131 -134
  44. data/test/test_appscriptreference.rb +96 -99
  45. data/test/test_codecs.rb +166 -168
  46. data/test/test_findapp.rb +13 -16
  47. data/test/test_mactypes.rb +70 -72
  48. data/test/test_osax.rb +46 -48
  49. data/test/testall.sh +4 -4
  50. metadata +8 -7
@@ -1,72 +1,72 @@
1
1
  /*
2
- File: AESendThreadSafe.c
3
-
4
- Contains: Code to send Apple events in a thread-safe manner.
5
-
6
- Written by: DTS
7
-
8
- Copyright: Copyright (c) 2007 Apple Inc. All Rights Reserved.
9
-
10
- Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc.
11
- ("Apple") in consideration of your agreement to the following
12
- terms, and your use, installation, modification or
13
- redistribution of this Apple software constitutes acceptance of
14
- these terms. If you do not agree with these terms, please do
15
- not use, install, modify or redistribute this Apple software.
16
-
17
- In consideration of your agreement to abide by the following
18
- terms, and subject to these terms, Apple grants you a personal,
19
- non-exclusive license, under Apple's copyrights in this
20
- original Apple software (the "Apple Software"), to use,
21
- reproduce, modify and redistribute the Apple Software, with or
22
- without modifications, in source and/or binary forms; provided
23
- that if you redistribute the Apple Software in its entirety and
24
- without modifications, you must retain this notice and the
25
- following text and disclaimers in all such redistributions of
26
- the Apple Software. Neither the name, trademarks, service marks
27
- or logos of Apple Inc. may be used to endorse or promote
28
- products derived from the Apple Software without specific prior
29
- written permission from Apple. Except as expressly stated in
30
- this notice, no other rights or licenses, express or implied,
31
- are granted by Apple herein, including but not limited to any
32
- patent rights that may be infringed by your derivative works or
33
- by other works in which the Apple Software may be incorporated.
34
-
35
- The Apple Software is provided by Apple on an "AS IS" basis.
36
- APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
37
- WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT,
38
- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING
39
- THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
40
- COMBINATION WITH YOUR PRODUCTS.
41
-
42
- IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT,
43
- INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
44
- TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
45
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY
46
- OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
47
- OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY
48
- OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR
49
- OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF
50
- SUCH DAMAGE.
51
-
52
- Change History (most recent first):
53
-
54
- $Log: AESendThreadSafe.c,v $
55
- Revision 1.3 2007/02/27 10:45:15
56
- In the destructor, add an assert that the thread-local storage has been set to NULL. Also fixed a comment typo.
57
-
58
- Revision 1.2 2007/02/12 11:59:09
59
- Added a type cast for the malloc result.
60
-
61
- Revision 1.1 2007/02/09 10:55:24
62
- First checked in.
2
+ File: AESendThreadSafe.c
3
+
4
+ Contains: Code to send Apple events in a thread-safe manner.
5
+
6
+ Written by: DTS
7
+
8
+ Copyright: Copyright (c) 2007 Apple Inc. All Rights Reserved.
9
+
10
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc.
11
+ ("Apple") in consideration of your agreement to the following
12
+ terms, and your use, installation, modification or
13
+ redistribution of this Apple software constitutes acceptance of
14
+ these terms. If you do not agree with these terms, please do
15
+ not use, install, modify or redistribute this Apple software.
16
+
17
+ In consideration of your agreement to abide by the following
18
+ terms, and subject to these terms, Apple grants you a personal,
19
+ non-exclusive license, under Apple's copyrights in this
20
+ original Apple software (the "Apple Software"), to use,
21
+ reproduce, modify and redistribute the Apple Software, with or
22
+ without modifications, in source and/or binary forms; provided
23
+ that if you redistribute the Apple Software in its entirety and
24
+ without modifications, you must retain this notice and the
25
+ following text and disclaimers in all such redistributions of
26
+ the Apple Software. Neither the name, trademarks, service marks
27
+ or logos of Apple Inc. may be used to endorse or promote
28
+ products derived from the Apple Software without specific prior
29
+ written permission from Apple. Except as expressly stated in
30
+ this notice, no other rights or licenses, express or implied,
31
+ are granted by Apple herein, including but not limited to any
32
+ patent rights that may be infringed by your derivative works or
33
+ by other works in which the Apple Software may be incorporated.
34
+
35
+ The Apple Software is provided by Apple on an "AS IS" basis.
36
+ APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
37
+ WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT,
38
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING
39
+ THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
40
+ COMBINATION WITH YOUR PRODUCTS.
41
+
42
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT,
43
+ INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
44
+ TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
45
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY
46
+ OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
47
+ OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY
48
+ OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR
49
+ OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF
50
+ SUCH DAMAGE.
51
+
52
+ Change History (most recent first):
53
+
54
+ $Log: AESendThreadSafe.c,v $
55
+ Revision 1.3 2007/02/27 10:45:15
56
+ In the destructor, add an assert that the thread-local storage has been set to NULL. Also fixed a comment typo.
57
+
58
+ Revision 1.2 2007/02/12 11:59:09
59
+ Added a type cast for the malloc result.
60
+
61
+ Revision 1.1 2007/02/09 10:55:24
62
+ First checked in.
63
63
 
64
64
 
65
65
  */
66
66
 
67
67
  /*
68
68
 
69
- 2007/06/24 -- Modified by HAS to make AESendMessageThreadSafeSynchronous API-compatible with AESendMessage; renamed SendMessageThreadSafe.
69
+ 2007/06/24 -- Modified by HAS to make AESendMessageThreadSafeSynchronous API-compatible with AESendMessage; renamed SendMessageThreadSafe.
70
70
 
71
71
  */
72
72
 
@@ -80,53 +80,53 @@ First checked in.
80
80
  /////////////////////////////////////////////////////////////////
81
81
 
82
82
  /*
83
- How It Works
84
- ------------
85
- The basic idea behind this module is that it uses per-thread storage to keep
86
- track of an Apple event reply for any given thread. The first time that the
87
- thread calls AESendMessageThreadSafeSynchronous, the per-thread storage will
88
- not be initialised and the code will grab an Apple event reply port and
89
- assign it to the per-thread storage. Subsequent calls to AESendMessageThreadSafeSynchronous
90
- will continue to use that port. When the thread dies, pthreads will automatically
91
- call the destructor for the per-thread storage, and that will clean up the port.
92
-
93
- Because we can't dispose of the reply port (without triggering the Apple
94
- Event Manager bug that's the reason we wrote this code in the first place),
95
- the destructor doesn't actually dispose of the port. Rather, it adds the
96
- port to a pool of ports that are available for reuse. The next time a thread
97
- needs to allocate a port, it will grab it from the pool rather than allocating
98
- it from scratch.
99
-
100
- This technique means that the code still 'leaks' Apple event reply ports, but
101
- the size of the leak is limited to the maximum number of threads that you run
102
- simultaneously. This isn't a problem in practice.
83
+ How It Works
84
+ ------------
85
+ The basic idea behind this module is that it uses per-thread storage to keep
86
+ track of an Apple event reply for any given thread. The first time that the
87
+ thread calls AESendMessageThreadSafeSynchronous, the per-thread storage will
88
+ not be initialised and the code will grab an Apple event reply port and
89
+ assign it to the per-thread storage. Subsequent calls to AESendMessageThreadSafeSynchronous
90
+ will continue to use that port. When the thread dies, pthreads will automatically
91
+ call the destructor for the per-thread storage, and that will clean up the port.
92
+
93
+ Because we can't dispose of the reply port (without triggering the Apple
94
+ Event Manager bug that's the reason we wrote this code in the first place),
95
+ the destructor doesn't actually dispose of the port. Rather, it adds the
96
+ port to a pool of ports that are available for reuse. The next time a thread
97
+ needs to allocate a port, it will grab it from the pool rather than allocating
98
+ it from scratch.
99
+
100
+ This technique means that the code still 'leaks' Apple event reply ports, but
101
+ the size of the leak is limited to the maximum number of threads that you run
102
+ simultaneously. This isn't a problem in practice.
103
103
  */
104
104
 
105
105
  /////////////////////////////////////////////////////////////////
106
106
 
107
- // The PerThreadStorage structure is a trivial wrapper around the Mach port.
108
- // I added this because I need to attach this structure a thread using
109
- // per-thread storage. The API for that (<x-man-page://3/pthread_setspecific>)
110
- // is pointer based. I could've just cast the Mach port to a (void *), but
111
- // that's ugly because of a) pointer size issues (are pointers always bigger than
107
+ // The PerThreadStorage structure is a trivial wrapper around the Mach port.
108
+ // I added this because I need to attach this structure a thread using
109
+ // per-thread storage. The API for that (<x-man-page://3/pthread_setspecific>)
110
+ // is pointer based. I could've just cast the Mach port to a (void *), but
111
+ // that's ugly because of a) pointer size issues (are pointers always bigger than
112
112
  // ints?), and b) because it implies an equivalent between NULL and MACH_PORT_NULL.
113
113
  // Given this, I simply decided to create a structure to wrap the Mach port.
114
114
 
115
115
  enum {
116
- kPerThreadStorageMagic = 'PTSm'
116
+ kPerThreadStorageMagic = 'PTSm'
117
117
  };
118
118
 
119
119
  struct PerThreadStorage {
120
- OSType magic; // must be kPerThreadStorageMagic
121
- mach_port_t port;
120
+ OSType magic; // must be kPerThreadStorageMagic
121
+ mach_port_t port;
122
122
  };
123
123
  typedef struct PerThreadStorage PerThreadStorage;
124
124
 
125
- // The following static variables manage the per-thread storage key
126
- // (sPerThreadStorageKey) and the pool of Mach ports (wrapped in
125
+ // The following static variables manage the per-thread storage key
126
+ // (sPerThreadStorageKey) and the pool of Mach ports (wrapped in
127
127
  // PerThreadStorage structures) that are not currently attached to a thread.
128
128
 
129
- static pthread_once_t sInited = PTHREAD_ONCE_INIT; // covers initialisation of all of the
129
+ static pthread_once_t sInited = PTHREAD_ONCE_INIT; // covers initialisation of all of the
130
130
  // following static variables
131
131
 
132
132
  static OSStatus sPerThreadStorageKeyInitErrNum; // latches result of initialisation
@@ -134,247 +134,247 @@ static OSStatus sPerThreadStorageKeyInitErrNum; // latches result of
134
134
  static pthread_key_t sPerThreadStorageKey = 0; // key for our per-thread storage
135
135
 
136
136
  static pthread_mutex_t sPoolMutex; // protects sPool
137
- static CFMutableArrayRef sPool; // array of (PerThreadStorage *), holds
138
- // the ports that aren't currently bound to
137
+ static CFMutableArrayRef sPool; // array of (PerThreadStorage *), holds
138
+ // the ports that aren't currently bound to
139
139
  // a thread
140
140
 
141
141
  static void PerThreadStorageDestructor(void *keyValue); // forward declaration
142
142
 
143
143
  static void InitRoutine(void)
144
- // Call once (via pthread_once) to initialise various static variables.
144
+ // Call once (via pthread_once) to initialise various static variables.
145
145
  {
146
- OSStatus err;
147
-
148
- // Create the per-thread storage key. Note that we assign a destructor to this key;
149
- // pthreads call the destructor to clean up that item of per-thread storage whenever
150
- // a thread terminates.
151
-
152
- err = (OSStatus) pthread_key_create(&sPerThreadStorageKey, PerThreadStorageDestructor);
153
-
154
- // Create the pool of Mach ports that aren't bound to any thread, and its associated
155
- // lock. The pool starts out empty.
156
-
157
- if (err == noErr) {
158
- err = (OSStatus) pthread_mutex_init(&sPoolMutex, NULL);
159
- }
160
- if (err == noErr) {
161
- sPool = CFArrayCreateMutable(NULL, 0, NULL);
162
- if (sPool == NULL) {
163
- err = coreFoundationUnknownErr;
164
- }
146
+ OSStatus err;
147
+
148
+ // Create the per-thread storage key. Note that we assign a destructor to this key;
149
+ // pthreads call the destructor to clean up that item of per-thread storage whenever
150
+ // a thread terminates.
151
+
152
+ err = (OSStatus) pthread_key_create(&sPerThreadStorageKey, PerThreadStorageDestructor);
153
+
154
+ // Create the pool of Mach ports that aren't bound to any thread, and its associated
155
+ // lock. The pool starts out empty.
156
+
157
+ if (err == noErr) {
158
+ err = (OSStatus) pthread_mutex_init(&sPoolMutex, NULL);
159
+ }
160
+ if (err == noErr) {
161
+ sPool = CFArrayCreateMutable(NULL, 0, NULL);
162
+ if (sPool == NULL) {
163
+ err = coreFoundationUnknownErr;
165
164
  }
166
- assert(err == 0);
167
-
168
- sPerThreadStorageKeyInitErrNum = err;
165
+ }
166
+ assert(err == 0);
167
+
168
+ sPerThreadStorageKeyInitErrNum = err;
169
169
  }
170
170
 
171
171
  static OSStatus AllocatePortFromPool(PerThreadStorage **storagePtr)
172
- // Grab a Mach port from sPool; if sPool is empty, create one.
172
+ // Grab a Mach port from sPool; if sPool is empty, create one.
173
173
  {
174
- OSStatus err;
175
- OSStatus junk;
176
- PerThreadStorage * storage;
177
-
178
- assert( storagePtr != NULL);
179
- assert(*storagePtr == NULL);
180
-
181
- storage = NULL;
182
-
183
- // First try to get an entry from pool. We try to grab the last one because
184
- // that minimises the amount of copying that CFArrayRemoveValueAtIndex has to
185
- // do.
186
-
187
- err = (OSStatus) pthread_mutex_lock(&sPoolMutex);
188
- if (err == noErr) {
189
- CFIndex poolCount;
190
-
191
- poolCount = CFArrayGetCount(sPool);
192
- if (poolCount > 0) {
193
- storage = (PerThreadStorage *) CFArrayGetValueAtIndex(sPool, poolCount - 1);
194
- CFArrayRemoveValueAtIndex(sPool, poolCount - 1);
195
- }
196
-
197
- junk = (OSStatus) pthread_mutex_unlock(&sPoolMutex);
198
- assert(junk == noErr);
199
- }
174
+ OSStatus err;
175
+ OSStatus junk;
176
+ PerThreadStorage * storage;
200
177
 
201
- // If we failed to find an entry in the pool, create a new one.
202
-
203
- if ( (err == noErr) && (storage == NULL) ) {
204
- storage = (PerThreadStorage *) malloc(sizeof(*storage));
205
- if (storage == NULL) {
206
- err = memFullErr;
207
- } else {
208
- storage->magic = kPerThreadStorageMagic;
209
- storage->port = MACH_PORT_NULL;
210
-
211
- err = (OSStatus) mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &storage->port);
212
- if (err != noErr) {
213
- assert(storage->port == MACH_PORT_NULL);
214
- free(storage);
215
- storage = NULL;
216
- }
217
- }
178
+ assert( storagePtr != NULL);
179
+ assert(*storagePtr == NULL);
180
+
181
+ storage = NULL;
182
+
183
+ // First try to get an entry from pool. We try to grab the last one because
184
+ // that minimises the amount of copying that CFArrayRemoveValueAtIndex has to
185
+ // do.
186
+
187
+ err = (OSStatus) pthread_mutex_lock(&sPoolMutex);
188
+ if (err == noErr) {
189
+ CFIndex poolCount;
190
+
191
+ poolCount = CFArrayGetCount(sPool);
192
+ if (poolCount > 0) {
193
+ storage = (PerThreadStorage *) CFArrayGetValueAtIndex(sPool, poolCount - 1);
194
+ CFArrayRemoveValueAtIndex(sPool, poolCount - 1);
218
195
  }
219
- if (err == noErr) {
220
- *storagePtr = storage;
196
+
197
+ junk = (OSStatus) pthread_mutex_unlock(&sPoolMutex);
198
+ assert(junk == noErr);
199
+ }
200
+
201
+ // If we failed to find an entry in the pool, create a new one.
202
+
203
+ if ( (err == noErr) && (storage == NULL) ) {
204
+ storage = (PerThreadStorage *) malloc(sizeof(*storage));
205
+ if (storage == NULL) {
206
+ err = memFullErr;
207
+ } else {
208
+ storage->magic = kPerThreadStorageMagic;
209
+ storage->port = MACH_PORT_NULL;
210
+
211
+ err = (OSStatus) mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &storage->port);
212
+ if (err != noErr) {
213
+ assert(storage->port == MACH_PORT_NULL);
214
+ free(storage);
215
+ storage = NULL;
216
+ }
221
217
  }
222
-
223
- assert( (err == noErr) == (*storagePtr != NULL) );
224
- assert( (*storagePtr == NULL) || ((*storagePtr)->magic == kPerThreadStorageMagic) );
225
- assert( (*storagePtr == NULL) || ((*storagePtr)->port != MACH_PORT_NULL) );
226
-
227
- return err;
218
+ }
219
+ if (err == noErr) {
220
+ *storagePtr = storage;
221
+ }
222
+
223
+ assert( (err == noErr) == (*storagePtr != NULL) );
224
+ assert( (*storagePtr == NULL) || ((*storagePtr)->magic == kPerThreadStorageMagic) );
225
+ assert( (*storagePtr == NULL) || ((*storagePtr)->port != MACH_PORT_NULL) );
226
+
227
+ return err;
228
228
  }
229
229
 
230
230
  static void ReturnPortToPool(PerThreadStorage * storage)
231
- // Returns a port to sPool.
231
+ // Returns a port to sPool.
232
232
  {
233
- OSStatus err;
233
+ OSStatus err;
234
234
 
235
- assert(storage != NULL);
236
- assert(storage->magic == kPerThreadStorageMagic);
237
- assert(storage->port != MACH_PORT_NULL);
235
+ assert(storage != NULL);
236
+ assert(storage->magic == kPerThreadStorageMagic);
237
+ assert(storage->port != MACH_PORT_NULL);
238
238
 
239
- err = (OSStatus) pthread_mutex_lock(&sPoolMutex);
240
- if (err == noErr) {
241
- CFArrayAppendValue(sPool, storage);
242
-
243
- err = (OSStatus) pthread_mutex_unlock(&sPoolMutex);
244
- }
245
- assert(err == noErr);
239
+ err = (OSStatus) pthread_mutex_lock(&sPoolMutex);
240
+ if (err == noErr) {
241
+ CFArrayAppendValue(sPool, storage);
242
+
243
+ err = (OSStatus) pthread_mutex_unlock(&sPoolMutex);
244
+ }
245
+ assert(err == noErr);
246
246
  }
247
247
 
248
248
  // Main Thread Notes
249
249
  // -----------------
250
- // There are two reasons why we don't assign a reply port to the main thread.
251
- // First, the main thread already has a reply port created for it by Apple
252
- // Event Manager. Thus, we don't need a specific reply port. Also, the
253
- // destructor for per-thread storage isn't called for the main thread, so
254
- // we wouldn't get a chance to clean up (although that's not really a problem
250
+ // There are two reasons why we don't assign a reply port to the main thread.
251
+ // First, the main thread already has a reply port created for it by Apple
252
+ // Event Manager. Thus, we don't need a specific reply port. Also, the
253
+ // destructor for per-thread storage isn't called for the main thread, so
254
+ // we wouldn't get a chance to clean up (although that's not really a problem
255
255
  // in practice).
256
256
 
257
257
  static OSStatus BindReplyMachPortToThread(mach_port_t *replyPortPtr)
258
- // Get a reply port for this thread, remembering that we've done this
259
- // in per-thread storage.
260
- //
261
- // On success, *replyPortPtr is the port to use for this thread's reply
262
- // port. It will be MACH_PORT_NULL if you call it from the main thread.
258
+ // Get a reply port for this thread, remembering that we've done this
259
+ // in per-thread storage.
260
+ //
261
+ // On success, *replyPortPtr is the port to use for this thread's reply
262
+ // port. It will be MACH_PORT_NULL if you call it from the main thread.
263
263
  {
264
- OSStatus err;
265
-
266
- assert( replyPortPtr != NULL);
267
- assert(*replyPortPtr == MACH_PORT_NULL);
268
-
269
- // Initialise ourselves the first time that we're called.
270
-
271
- err = (OSStatus) pthread_once(&sInited, InitRoutine);
272
-
273
- // If something went wrong, return the latched error.
274
-
275
- if ( (err == noErr) && (sPerThreadStorageKeyInitErrNum != noErr) ) {
276
- err = sPerThreadStorageKeyInitErrNum;
277
- }
278
-
279
- // Now do the real work.
280
-
281
- if (err == noErr) {
282
- if ( pthread_main_np() ) {
283
- // This is the main thread, so do nothing; leave *replyPortPtr set
284
- // to MACH_PORT_NULL.
285
- assert(*replyPortPtr == MACH_PORT_NULL);
286
- } else {
287
- PerThreadStorage * storage;
288
-
289
- // Get the per-thread storage for this thread.
290
-
291
- storage = (PerThreadStorage *) pthread_getspecific(sPerThreadStorageKey);
292
- if (storage == NULL) {
293
-
294
- // The per-thread storage hasn't been allocated yet for this specific
295
- // thread. Let's go allocate it and attach it to this thread.
296
-
297
- err = AllocatePortFromPool(&storage);
298
- if (err == noErr) {
299
- err = (OSStatus) pthread_setspecific(sPerThreadStorageKey, (void *) storage);
300
- if (err != noErr) {
301
- ReturnPortToPool(storage);
302
- storage = NULL;
303
- }
304
- }
305
- }
306
- assert( (err == noErr) == (storage != NULL) );
307
-
308
- // If all went well, copy the port out to our client.
309
-
310
- if (err == noErr) {
311
- assert(storage->magic == kPerThreadStorageMagic);
312
- assert(storage->port != MACH_PORT_NULL);
313
- *replyPortPtr = storage->port;
314
- }
264
+ OSStatus err;
265
+
266
+ assert( replyPortPtr != NULL);
267
+ assert(*replyPortPtr == MACH_PORT_NULL);
268
+
269
+ // Initialise ourselves the first time that we're called.
270
+
271
+ err = (OSStatus) pthread_once(&sInited, InitRoutine);
272
+
273
+ // If something went wrong, return the latched error.
274
+
275
+ if ( (err == noErr) && (sPerThreadStorageKeyInitErrNum != noErr) ) {
276
+ err = sPerThreadStorageKeyInitErrNum;
277
+ }
278
+
279
+ // Now do the real work.
280
+
281
+ if (err == noErr) {
282
+ if ( pthread_main_np() ) {
283
+ // This is the main thread, so do nothing; leave *replyPortPtr set
284
+ // to MACH_PORT_NULL.
285
+ assert(*replyPortPtr == MACH_PORT_NULL);
286
+ } else {
287
+ PerThreadStorage * storage;
288
+
289
+ // Get the per-thread storage for this thread.
290
+
291
+ storage = (PerThreadStorage *) pthread_getspecific(sPerThreadStorageKey);
292
+ if (storage == NULL) {
293
+
294
+ // The per-thread storage hasn't been allocated yet for this specific
295
+ // thread. Let's go allocate it and attach it to this thread.
296
+
297
+ err = AllocatePortFromPool(&storage);
298
+ if (err == noErr) {
299
+ err = (OSStatus) pthread_setspecific(sPerThreadStorageKey, (void *) storage);
300
+ if (err != noErr) {
301
+ ReturnPortToPool(storage);
302
+ storage = NULL;
303
+ }
315
304
  }
305
+ }
306
+ assert( (err == noErr) == (storage != NULL) );
307
+
308
+ // If all went well, copy the port out to our client.
309
+
310
+ if (err == noErr) {
311
+ assert(storage->magic == kPerThreadStorageMagic);
312
+ assert(storage->port != MACH_PORT_NULL);
313
+ *replyPortPtr = storage->port;
314
+ }
316
315
  }
316
+ }
317
317
 
318
- // no error + MACH_PORT_NULL is a valid response if we're on the main
319
- // thread.
320
- //
321
- // assert( (err == noErr) == (*replyPortPtr != MACH_PORT_NULL) );
322
- assert( (*replyPortPtr == MACH_PORT_NULL) || (err == noErr) );
323
-
324
- return err;
318
+ // no error + MACH_PORT_NULL is a valid response if we're on the main
319
+ // thread.
320
+ //
321
+ // assert( (err == noErr) == (*replyPortPtr != MACH_PORT_NULL) );
322
+ assert( (*replyPortPtr == MACH_PORT_NULL) || (err == noErr) );
323
+
324
+ return err;
325
325
  }
326
326
 
327
327
  static void PerThreadStorageDestructor(void *keyValue)
328
- // Called by pthreads when a thread dies and it has a non-null value for our
329
- // per-thread storage key. We use this callback to return the thread's
330
- // Apple event reply port to the pool.
328
+ // Called by pthreads when a thread dies and it has a non-null value for our
329
+ // per-thread storage key. We use this callback to return the thread's
330
+ // Apple event reply port to the pool.
331
331
  {
332
- PerThreadStorage * storage;
332
+ PerThreadStorage * storage;
333
+
334
+ storage = (PerThreadStorage *) keyValue;
335
+ assert(storage != NULL); // pthread won't call us if it's NULL
336
+ assert(storage->magic == kPerThreadStorageMagic);
337
+ assert(storage->port != MACH_PORT_NULL);
338
+
339
+ // Return the port associated with this thread to the pool.
333
340
 
334
- storage = (PerThreadStorage *) keyValue;
335
- assert(storage != NULL); // pthread won't call us if it's NULL
336
- assert(storage->magic == kPerThreadStorageMagic);
337
- assert(storage->port != MACH_PORT_NULL);
338
-
339
- // Return the port associated with this thread to the pool.
340
-
341
- ReturnPortToPool(storage);
341
+ ReturnPortToPool(storage);
342
342
 
343
- // pthreads has already set this thread's per-thread storage for our key to
344
- // NULL before calling us. So we don't need to do anything to remove it.
343
+ // pthreads has already set this thread's per-thread storage for our key to
344
+ // NULL before calling us. So we don't need to do anything to remove it.
345
345
 
346
- assert( pthread_getspecific(sPerThreadStorageKey) == NULL );
346
+ assert( pthread_getspecific(sPerThreadStorageKey) == NULL );
347
347
  }
348
348
 
349
349
  OSStatus SendMessageThreadSafe(
350
- AppleEvent * eventPtr,
351
- AppleEvent * replyPtr,
352
- AESendMode sendMode,
353
- long timeOutInTicks
354
- )
355
- // See comment in header.
350
+ AppleEvent * eventPtr,
351
+ AppleEvent * replyPtr,
352
+ AESendMode sendMode,
353
+ long timeOutInTicks
354
+ )
355
+ // See comment in header.
356
356
  {
357
- OSStatus err = noErr;
358
- mach_port_t replyPort;
359
- assert(eventPtr != NULL);
360
- assert(replyPtr != NULL);
361
-
362
- if (sendMode && kAEWaitReply) {
363
- replyPort = MACH_PORT_NULL;
364
-
365
- // Set up the reply port if necessary.
366
-
367
- err = BindReplyMachPortToThread(&replyPort);
368
- if ( (err == noErr) && (replyPort != MACH_PORT_NULL) ) {
369
- err = AEPutAttributePtr(eventPtr, keyReplyPortAttr, typeMachPort, &replyPort, sizeof(replyPort));
370
- }
371
- }
372
-
373
- // Call through to AESendMessage.
374
-
375
- if (err == noErr) {
376
- err = AESendMessage(eventPtr, replyPtr, sendMode, timeOutInTicks);
357
+ OSStatus err = noErr;
358
+ mach_port_t replyPort;
359
+ assert(eventPtr != NULL);
360
+ assert(replyPtr != NULL);
361
+
362
+ if (sendMode && kAEWaitReply) {
363
+ replyPort = MACH_PORT_NULL;
364
+
365
+ // Set up the reply port if necessary.
366
+
367
+ err = BindReplyMachPortToThread(&replyPort);
368
+ if ( (err == noErr) && (replyPort != MACH_PORT_NULL) ) {
369
+ err = AEPutAttributePtr(eventPtr, keyReplyPortAttr, typeMachPort, &replyPort, sizeof(replyPort));
377
370
  }
378
-
379
- return err;
371
+ }
372
+
373
+ // Call through to AESendMessage.
374
+
375
+ if (err == noErr) {
376
+ err = AESendMessage(eventPtr, replyPtr, sendMode, timeOutInTicks);
377
+ }
378
+
379
+ return err;
380
380
  }