File: thread.m

package info (click to toggle)
gnustep-base 1.31.1-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 26,580 kB
  • sloc: objc: 239,446; ansic: 36,519; cpp: 122; sh: 112; makefile: 100; xml: 32
file content (212 lines) | stat: -rw-r--r-- 6,280 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
#import "ObjectTesting.h"

#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSObject.h>
#import <Foundation/NSFileHandle.h>
#import <Foundation/NSNotification.h>
#import <Foundation/NSThread.h>
#import <Foundation/NSTimer.h>
#import <Foundation/NSRunLoop.h>

@interface ThreadTest : NSObject {
  char  acceptEmptyBlocks;
  char  acceptTimerBlocks;
  char  blockForEmpty;
  char  blockForInput;
  char  blockForTimer;
  char  limitForEmpty;
  char  limitForInput;
  char  limitForTimer;
  char  moreForEmpty;
  char  moreForInput;
  char  moreForTimer;
  char  performed;
}
- (void) notified: (NSNotification*)n;
- (void) timeout: (NSTimer*)t;
- (void) thread1: (id)o;
@end

@implementation ThreadTest

- (void) notified: (NSNotification*)n
{
  NSLog(@"Notified: %@", n);
}

- (void) timeout: (NSTimer*)t
{
}

- (void) thread1: (id)o
{
  NSAutoreleasePool     *pool = [NSAutoreleasePool new];
  NSNotificationCenter	*nc;
  NSRunLoop             *loop;
  NSFileHandle          *fh;
  NSTimer               *timer;
  NSDate                *end;
  NSDate                *start;
 
  nc = [NSNotificationCenter defaultCenter];
  loop = [NSRunLoop currentRunLoop];

  end = [loop limitDateForMode: NSDefaultRunLoopMode];
  if (end == nil)
    limitForEmpty = 'N';
  else
    limitForEmpty = 'Y';

  end = [NSDate dateWithTimeIntervalSinceNow: 0.2];
  start = [NSDate date];
  if ([loop runMode: NSDefaultRunLoopMode beforeDate: end] == YES)
    moreForEmpty = 'Y';
  else
    moreForEmpty = 'N';
  if (fabs([start timeIntervalSinceNow]) < 0.01)
    blockForEmpty = 'N';
  else
    blockForEmpty = 'Y';
  
  end = [NSDate dateWithTimeIntervalSinceNow: 0.2];
  start = [NSDate date];
  [loop acceptInputForMode: NSDefaultRunLoopMode beforeDate: end];
  if (fabs([start timeIntervalSinceNow]) < 0.01)
    acceptEmptyBlocks = 'N';
  else
    acceptEmptyBlocks = 'Y';
  
  timer = [NSTimer timerWithTimeInterval: 2.0
                                  target: self
                                selector: @selector(timeout:)
                                userInfo: nil
                                 repeats: NO];
  [loop addTimer: timer forMode: NSDefaultRunLoopMode];
  end = [loop limitDateForMode: NSDefaultRunLoopMode];
  if (fabs([end timeIntervalSinceDate: [timer fireDate]]) < 0.01)
    limitForTimer = 'Y';
  else
    limitForTimer = 'N';
  end = [NSDate dateWithTimeIntervalSinceNow: 0.2];
  start = [NSDate date];
  if ([loop runMode: NSDefaultRunLoopMode beforeDate: end] == YES)
    moreForTimer = 'Y';
  else
    moreForTimer = 'N';
  if (fabs([start timeIntervalSinceNow]) < 0.01)
    blockForTimer = 'N';
  else
    blockForTimer = 'Y';

  end = [NSDate dateWithTimeIntervalSinceNow: 0.2];
  start = [NSDate date];
  [loop acceptInputForMode: NSDefaultRunLoopMode beforeDate: end];
  if (fabs([start timeIntervalSinceNow]) < 0.01)
    acceptTimerBlocks = 'N';
  else
    acceptTimerBlocks = 'Y';
  
  [timer invalidate];

  fh = [[NSPipe pipe] fileHandleForReading];
  [nc addObserver: self selector:@selector(notified:) 
  	     name: nil object:fh];
  [fh readInBackgroundAndNotify];
  end = [loop limitDateForMode: NSDefaultRunLoopMode];
  if ([end isEqual: [NSDate distantFuture]] == YES)
    limitForInput = 'Y';
  else
    limitForInput = 'N';
  end = [NSDate dateWithTimeIntervalSinceNow: 0.2];
  start = [NSDate date];
  if ([loop runMode: NSDefaultRunLoopMode beforeDate: end] == YES)
    moreForInput = 'Y';
  else
    moreForInput = 'N';
  [timer invalidate];
  if (fabs([start timeIntervalSinceNow]) < 0.01)
    blockForInput = 'N';
  else
    blockForInput = 'Y';
  [nc removeObserver: self];
  [pool release];
}

- (void) thread2: (id)o
{
  NSAutoreleasePool     *pool = [NSAutoreleasePool new];
  NSRunLoop             *loop;
  NSDate                *end;
 
  loop = [NSRunLoop currentRunLoop];

  [NSTimer scheduledTimerWithTimeInterval: 2.0
                                   target: self
                                 selector: @selector(timeout:)
                                 userInfo: nil
                                  repeats: NO];

  end = [NSDate dateWithTimeIntervalSinceNow: 2.0];
  while ([end timeIntervalSinceNow] > 0)
    {
      [loop runUntilDate: end];
    }
  [pool release];
}

- (void) threadEvent: (id)ignored
{
  performed = 'Y';
}

- (void) run
{
  NSDate                *until = [NSDate dateWithTimeIntervalSinceNow: 5.0];
  NSThread              *t;
  
  [NSTimer scheduledTimerWithTimeInterval: 5.0
                                   target: self
                                 selector: @selector(timeout:)
                                 userInfo: nil
                                  repeats: YES];

  [NSThread detachNewThreadSelector: @selector(thread1:)
                           toTarget: self
                         withObject: nil];
  t = [[NSThread alloc] initWithTarget: self
                              selector: @selector(thread2:)
                                object: nil];
  [t start];

  [self performSelector: @selector(threadEvent:)
               onThread: t
             withObject: nil
          waitUntilDone: NO];
  while ([until timeIntervalSinceNow] > 0)
    {
      [[NSRunLoop currentRunLoop] runUntilDate: until];
    }

  PASS(acceptEmptyBlocks == 'N', "Accept with no inputs or timers will exit");
  PASS(acceptTimerBlocks == 'Y', "Accept with timers will not exit");
  PASS(blockForEmpty == 'N', "A loop with no inputs or timers will exit");
  PASS(blockForInput == 'Y', "A loop with an input source will block");
  PASS(blockForTimer == 'Y', "A loop with a timer will block");
  PASS(limitForEmpty == 'N', "A loop with no inputs or timers has no limit");
  PASS(limitForInput == 'Y', "A loop with an input source has distant future");
  PASS(limitForTimer == 'Y', "A loop with a timer has timer fire date");
  PASS(moreForEmpty == 'N', "A loop with no inputs or timers has no more");
  PASS(moreForInput == 'Y', "A loop with an input source has more");
  PASS(moreForTimer == 'Y', "A loop with a timer has more");
  PASS(performed == 'Y', "Methods will be performed in a loop without inputs");
}

@end

int main(int argc, char *argv[])
{
  NSAutoreleasePool *pool = [NSAutoreleasePool new];
  [[[ThreadTest new] autorelease] run];
  [pool release];
  return 0;
}