Ver código fonte

port: fix race when writing to cache buffer

osy 8 meses atrás
pai
commit
bbcc637187
1 arquivos alterados com 14 adições e 8 exclusões
  1. 14 8
      Sources/CocoaSpice/CSPort.m

+ 14 - 8
Sources/CocoaSpice/CSPort.m

@@ -26,6 +26,7 @@ static const NSInteger kMaxCacheBufferSize = 4096;
 @property (nonatomic, readwrite) SpicePortChannel *channel;
 @property (nonatomic, readwrite) SpicePortChannel *channel;
 @property (nonatomic, readwrite, weak) CSConnection *connection;
 @property (nonatomic, readwrite, weak) CSConnection *connection;
 @property (nonatomic) NSMutableData *cacheBuffer;
 @property (nonatomic) NSMutableData *cacheBuffer;
+@property (nonatomic) dispatch_queue_t cacheBufferQueue;
 
 
 @end
 @end
 
 
@@ -53,12 +54,14 @@ static void cs_port_data(SpicePortChannel *port,
     if (delegate) {
     if (delegate) {
         [delegate port:self didRecieveData:nsdata];
         [delegate port:self didRecieveData:nsdata];
     } else {
     } else {
-        [self.cacheBuffer appendData:nsdata];
-        if (self.cacheBuffer.length > kMaxCacheBufferSize) {
-            [self.cacheBuffer replaceBytesInRange:NSMakeRange(0, self.cacheBuffer.length-kMaxCacheBufferSize)
-                                        withBytes:NULL
-                                           length:0];
-        }
+        dispatch_async(self.cacheBufferQueue, ^{
+            [self.cacheBuffer appendData:nsdata];
+            if (self.cacheBuffer.length > kMaxCacheBufferSize) {
+                [self.cacheBuffer replaceBytesInRange:NSMakeRange(0, self.cacheBuffer.length-kMaxCacheBufferSize)
+                                            withBytes:NULL
+                                               length:0];
+            }
+        });
     }
     }
 }
 }
 
 
@@ -88,6 +91,7 @@ static void cs_port_write_cb(GObject *source_object,
 - (instancetype)initWithChannel:(SpicePortChannel *)channel {
 - (instancetype)initWithChannel:(SpicePortChannel *)channel {
     if (self = [self init]) {
     if (self = [self init]) {
         self.cacheBuffer = [NSMutableData data];
         self.cacheBuffer = [NSMutableData data];
+        self.cacheBufferQueue = dispatch_queue_create("CocoaSpice Cache Buffer Queue", NULL);
         self.channel = g_object_ref(channel);
         self.channel = g_object_ref(channel);
         g_signal_connect(channel, "notify::port-opened",
         g_signal_connect(channel, "notify::port-opened",
                          G_CALLBACK(cs_port_opened), (__bridge void *)self);
                          G_CALLBACK(cs_port_opened), (__bridge void *)self);
@@ -142,8 +146,10 @@ static void cs_port_write_cb(GObject *source_object,
 
 
 - (void)setDelegate:(id<CSPortDelegate>)delegate {
 - (void)setDelegate:(id<CSPortDelegate>)delegate {
     if (_delegate == NULL && self.cacheBuffer.length > 0) {
     if (_delegate == NULL && self.cacheBuffer.length > 0) {
-        [delegate port:self didRecieveData:self.cacheBuffer];
-        self.cacheBuffer.length = 0;
+        dispatch_async(self.cacheBufferQueue, ^{
+            [delegate port:self didRecieveData:self.cacheBuffer];
+            self.cacheBuffer.length = 0;
+        });
     }
     }
     _delegate = delegate;
     _delegate = delegate;
 }
 }