1//
2// Copyright (c) ZeroC, Inc. All rights reserved.
3//
4
5#import <objc/Ice.h>
6#import <hold/TestI.h>
7#import <TestCommon.h>
8
9#import <Foundation/Foundation.h>
10
11@implementation Timer
12-(id) init
13{
14    self = [super init];
15    if(self != nil)
16    {
17        queue = dispatch_queue_create("timer", NULL);
18    }
19    return self;
20}
21#if defined(__clang__) && !__has_feature(objc_arc)
22-(void) dealloc
23{
24    dispatch_release(queue);
25    [super dealloc];
26}
27#endif
28-(void) schedule:(void(^)(void))callback timeout:(ICEInt)t
29{
30    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
31    dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, t * NSEC_PER_MSEC), DISPATCH_TIME_FOREVER, 0);
32    dispatch_source_set_event_handler(timer, ^{
33            callback();
34            dispatch_source_cancel(timer);
35#if defined(__clang__) && !__has_feature(objc_arc)
36            dispatch_release(timer);
37#endif
38        });
39    dispatch_resume(timer);
40}
41@end
42
43@implementation HoldI
44-(id) init
45{
46    self = [super init];
47    if(self != nil)
48    {
49        timer = [Timer new];
50    }
51    return self;
52}
53#if defined(__clang__) && !__has_feature(objc_arc)
54-(void) dealloc
55{
56    [timer release];
57    [super dealloc];
58}
59#endif
60-(void) putOnHold:(ICEInt)milliSeconds current:(ICECurrent*)current
61{
62    if(milliSeconds < 0)
63    {
64        [current.adapter hold];
65    }
66    else if(milliSeconds == 0)
67    {
68        [current.adapter hold];
69        [current.adapter activate];
70    }
71    else
72    {
73        [timer schedule:^{
74                @try
75                {
76                    [current.adapter hold];
77                    [current.adapter activate];
78                }
79                @catch(ICEObjectAdapterDeactivatedException* ex)
80                {
81                }
82                @catch(id ex)
83                {
84                    test(NO);
85                }
86            } timeout:milliSeconds];
87    }
88}
89
90-(void) waitForHold:(ICECurrent*)current
91{
92    [timer schedule:^{
93            @try
94            {
95                [current.adapter waitForHold];
96                [current.adapter activate];
97            }
98            @catch(ICEObjectAdapterDeactivatedException* ex)
99            {
100                test(NO);
101            }
102            @catch(id ex)
103            {
104                test(NO);
105            }
106        } timeout:0];
107}
108
109-(ICEInt) set:(ICEInt)value delay:(ICEInt)delay current:(ICECurrent*)__unused current
110{
111    [NSThread sleepForTimeInterval:delay / 1000.0];
112    @synchronized(self)
113    {
114        ICEInt tmp = last;
115        last = value;
116        return tmp;
117    }
118    return 0;
119}
120
121-(void) setOneway:(ICEInt)value expected:(ICEInt)expected current:(ICECurrent*)__unused current
122{
123    @synchronized(self)
124    {
125        test(last == expected);
126        last = value;
127    }
128}
129
130-(void) shutdown:(ICECurrent*)current
131{
132    [current.adapter hold];
133    [[current.adapter getCommunicator] shutdown];
134}
135
136@end
137