Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(157)

Side by Side Diff: third_party/grpc/src/objective-c/RxLibrary/GRXConcurrentWriteable.m

Issue 1932353002: Initial checkin of gRPC to third_party/ Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 *
3 * Copyright 2015, Google Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
34 #import "GRXConcurrentWriteable.h"
35
36 #import <RxLibrary/GRXWriteable.h>
37
38 @interface GRXConcurrentWriteable ()
39 // This is atomic so that cancellation can nillify it from any thread.
40 @property(atomic, strong) id<GRXWriteable> writeable;
41 @end
42
43 @implementation GRXConcurrentWriteable {
44 dispatch_queue_t _writeableQueue;
45 // This ensures that writesFinishedWithError: is only sent once to the writeab le.
46 dispatch_once_t _alreadyFinished;
47 }
48
49 - (instancetype)init {
50 return [self initWithWriteable:nil];
51 }
52
53 // Designated initializer
54 - (instancetype)initWithWriteable:(id<GRXWriteable>)writeable {
55 if (self = [super init]) {
56 _writeableQueue = dispatch_get_main_queue();
57 _writeable = writeable;
58 }
59 return self;
60 }
61
62 - (void)enqueueValue:(id)value completionHandler:(void (^)())handler {
63 dispatch_async(_writeableQueue, ^{
64 // We're racing a possible cancellation performed by another thread. To turn all already-
65 // enqueued messages into noops, cancellation nillifies the writeable proper ty. If we get it
66 // before it's nil, we won the race.
67 id<GRXWriteable> writeable = self.writeable;
68 if (writeable) {
69 [writeable writeValue:value];
70 handler();
71 }
72 });
73 }
74
75 - (void)enqueueSuccessfulCompletion {
76 dispatch_async(_writeableQueue, ^{
77 dispatch_once(&_alreadyFinished, ^{
78 // Cancellation is now impossible. None of the other three blocks can run concurrently with
79 // this one.
80 [self.writeable writesFinishedWithError:nil];
81 // Skip any possible message to the wrapped writeable enqueued after this one.
82 self.writeable = nil;
83 });
84 });
85 }
86
87 - (void)cancelWithError:(NSError *)error {
88 NSAssert(error, @"For a successful completion, use enqueueSuccessfulCompletion .");
89 dispatch_once(&_alreadyFinished, ^{
90 // Skip any of the still-enqueued messages to the wrapped writeable. We use the atomic setter to
91 // nillify writeable because we might be running concurrently with the block s in
92 // _writeableQueue, and assignment with ARC isn't atomic.
93 id<GRXWriteable> writeable = self.writeable;
94 self.writeable = nil;
95
96 dispatch_async(_writeableQueue, ^{
97 [writeable writesFinishedWithError:error];
98 });
99 });
100 }
101
102 - (void)cancelSilently {
103 dispatch_once(&_alreadyFinished, ^{
104 // Skip any of the still-enqueued messages to the wrapped writeable. We use the atomic setter to
105 // nillify writeable because we might be running concurrently with the block s in
106 // _writeableQueue, and assignment with ARC isn't atomic.
107 self.writeable = nil;
108 });
109 }
110 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698