~ubuntu-branches/ubuntu/lucid/gnustep-base/lucid

« back to all changes in this revision

Viewing changes to Source/NSMessagePortNameServer.m

  • Committer: Bazaar Package Importer
  • Author(s): Luca Falavigna
  • Date: 2008-05-23 09:59:21 UTC
  • Revision ID: james.westby@ubuntu.com-20080523095921-7sr0kpyp5qfdko4u
Tags: 1.14.1-8ubuntu1
* Merge from Debian unstable, remaining Ubuntu changes:
  + debian/rules:
    - Add lpia to ALL_ARCHS supported architectures.
  + debian/control:
    - Add lpia architecture where needed.
  + debian/control{,.m4}:
    - Update Maintainer field as per spec.

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
#include "Foundation/NSDebug.h"
30
30
#include "Foundation/NSException.h"
31
31
#include "Foundation/NSLock.h"
 
32
#include "Foundation/NSDistributedLock.h"
32
33
#include "Foundation/NSMapTable.h"
33
34
#include "Foundation/NSPathUtilities.h"
34
35
#include "Foundation/NSPort.h"
77
78
 
78
79
 
79
80
@interface NSMessagePortNameServer (private)
 
81
+ (NSDistributedLock*) _fileLock;
80
82
+(NSString *) _pathForName: (NSString *)name;
81
83
@end
82
84
 
139
141
  return defaultServer;
140
142
}
141
143
 
142
 
 
 
144
+ (NSDistributedLock*) _fileLock
 
145
{
 
146
  NSDistributedLock     *dl;
 
147
 
 
148
  dl = [NSDistributedLock lockWithPath: [self _pathForName: nil]];
 
149
  if ([dl tryLock] == NO)
 
150
    {
 
151
      NSDate    *limit = [NSDate dateWithTimeIntervalSinceNow: 2.0];
 
152
 
 
153
      while (dl != nil && [dl tryLock] == NO)
 
154
        {
 
155
          CREATE_AUTORELEASE_POOL(pool);
 
156
 
 
157
          if ([limit timeIntervalSinceNow] > 0.0)
 
158
            {
 
159
              [NSThread sleepUntilDate:
 
160
                [NSDate dateWithTimeIntervalSinceNow: 0.1]];
 
161
            }
 
162
          else
 
163
            {
 
164
              if ([[dl lockDate] timeIntervalSinceNow] < -15.0)
 
165
                {
 
166
                  NS_DURING
 
167
                    {
 
168
                      [dl breakLock];
 
169
                    }
 
170
                  NS_HANDLER
 
171
                    {
 
172
                      NSLog(@"Failed to break lock on names for "
 
173
                        @"NSMessagePortNameServer: %@", localException);
 
174
                      dl = nil;
 
175
                    }
 
176
                  NS_ENDHANDLER
 
177
                }
 
178
              else
 
179
                {
 
180
                  NSLog(@"Failed to lock names for NSMessagePortNameServer");
 
181
                  dl = nil;
 
182
                }
 
183
            }
 
184
          RELEASE(pool);
 
185
        }
 
186
    }
 
187
  return dl;
 
188
}
 
189
 
 
190
/* Return the full path for the supplied port name or, if it's nil,
 
191
 * the path for the distributed lock protecting all names.
 
192
 */
143
193
+ (NSString *) _pathForName: (NSString *)name
144
194
{
145
195
  static NSString       *base_path = nil;
146
196
  NSString              *path;
147
197
  NSData                *data;
148
198
 
 
199
  if (name == nil)
 
200
    {
 
201
      name = @"lock";
 
202
    }
 
203
  else
 
204
    {
149
205
  /*
150
206
   * Make sure name is representable as a filename ... assume base64 encoded
151
207
   * strings are valid on all filesystems.
152
208
   */
153
209
  data = [name dataUsingEncoding: NSUTF8StringEncoding];
154
210
  data = [GSMimeDocument encodeBase64: data];
155
 
  name = [[NSString alloc] initWithData: data encoding: NSASCIIStringEncoding];
 
211
      name = [[NSString alloc] initWithData: data
 
212
                                   encoding: NSASCIIStringEncoding];
156
213
  AUTORELEASE(name);
 
214
    }
157
215
  [serverLock lock];
158
216
  if (!base_path)
159
217
    {
260
318
- (NSPort*) portForName: (NSString *)name
261
319
                 onHost: (NSString *)host
262
320
{
 
321
  NSDistributedLock     *dl;
263
322
  NSString      *path;
264
323
  FILE          *f;
265
324
  char          socket_path[512];
278
337
    }
279
338
 
280
339
  path = [[self class] _pathForName: name];
 
340
  if ((dl = [[self class] _fileLock]) == nil)
 
341
    {
 
342
      [NSException raise: NSGenericException
 
343
                  format: @"Failed to lock names for NSMessagePortNameServer"];
 
344
    }
281
345
  if (![[self class] _livePort: path])
282
346
    {
 
347
      [dl unlock];
283
348
      NSDebugLLog(@"NSMessagePort", @"not a live port");
284
349
      return nil;
285
350
    }
287
352
  f = fopen([path fileSystemRepresentation], "rt");
288
353
  if (!f)
289
354
    {
 
355
      [dl unlock];
290
356
      NSDebugLLog(@"NSMessagePort", @"can't open file (%m)");
291
357
      return nil;
292
358
    }
296
362
  fclose(f);
297
363
 
298
364
  NSDebugLLog(@"NSMessagePort", @"got %s", socket_path);
 
365
  [dl unlock];
299
366
 
300
367
  return [NSMessagePort _portWithName: (unsigned char*)socket_path
301
368
                             listener: NO];
306
373
{
307
374
  int                   fd;
308
375
  unsigned char         buf[32];
 
376
  NSDistributedLock     *dl;
309
377
  NSString              *path;
310
378
  const unsigned char   *socket_name;
311
379
  NSMutableArray        *a;
316
384
      [NSException raise: NSInvalidArgumentException
317
385
                  format: @"Attempted to register a non-NSMessagePort (%@)",
318
386
        port];
319
 
      return NO;
320
387
    }
321
388
 
322
389
  path = [[self class] _pathForName: name];
323
 
 
 
390
  if ((dl = [[self class] _fileLock]) == nil)
 
391
    {
 
392
      [NSException raise: NSGenericException
 
393
                  format: @"Failed to lock names for NSMessagePortNameServer"];
 
394
    }
324
395
  if ([[self class] _livePort: path])
325
396
    {
 
397
      [dl unlock];
326
398
      NSDebugLLog(@"NSMessagePort", @"fail, is a live port (%@)", name);
327
399
      return NO;
328
400
    }
330
402
  fd = open([path fileSystemRepresentation], O_CREAT|O_EXCL|O_WRONLY, 0600);
331
403
  if (fd < 0)
332
404
    {
 
405
      [dl unlock];
333
406
      NSDebugLLog(@"NSMessagePort", @"fail, can't open file (%@) for %@",
334
407
        path, name);
335
408
      return NO;
355
428
 
356
429
  [a addObject: [name copy]];
357
430
  [serverLock unlock];
 
431
  [dl unlock];
358
432
 
359
433
  return YES;
360
434
}
361
435
 
362
436
- (BOOL) removePortForName: (NSString *)name
363
437
{
 
438
  NSDistributedLock     *dl;
364
439
  NSString      *path;
365
440
 
366
441
  NSDebugLLog(@"NSMessagePort", @"removePortForName: %@", name);
367
442
  path = [[self class] _pathForName: name];
 
443
  if ((dl = [[self class] _fileLock]) == nil)
 
444
    {
 
445
      [NSException raise: NSGenericException
 
446
                  format: @"Failed to lock names for NSMessagePortNameServer"];
 
447
    }
368
448
  unlink([path fileSystemRepresentation]);
 
449
  [dl unlock];
369
450
  return YES;
370
451
}
371
452
 
405
486
{
406
487
  FILE                  *f;
407
488
  char                  socket_path[512];
 
489
  NSDistributedLock     *dl;
408
490
  NSString              *path;
409
491
  const unsigned char   *port_path;
410
492
 
411
493
  NSDebugLLog(@"NSMessagePort", @"removePort: %@  forName: %@", port, name);
412
494
 
413
495
  path = [[self class] _pathForName: name];
414
 
 
 
496
  if ((dl = [[self class] _fileLock]) == nil)
 
497
    {
 
498
      [NSException raise: NSGenericException
 
499
                  format: @"Failed to lock names for NSMessagePortNameServer"];
 
500
    }
415
501
  f = fopen([path fileSystemRepresentation], "rt");
416
502
  if (!f)
 
503
    {
 
504
      [dl unlock];
417
505
    return YES;
418
 
 
 
506
    }
419
507
  fgets(socket_path, sizeof(socket_path), f);
420
 
  if (strlen(socket_path) > 0) socket_path[strlen(socket_path) - 1] = 0;
421
 
 
 
508
  if (strlen(socket_path) > 0)
 
509
    {
 
510
      socket_path[strlen(socket_path) - 1] = 0;
 
511
    }
422
512
  fclose(f);
423
 
 
424
513
  port_path = [(NSMessagePort *)port _name];
425
 
 
426
514
  if (!strcmp((char*)socket_path, (char*)port_path))
427
515
    {
428
516
      unlink([path fileSystemRepresentation]);
429
517
    }
430
 
 
 
518
  [dl unlock];
431
519
  return YES;
432
520
}
433
521