Browse Source

Merge pull request #137 from MrMage/var-let-mutex

Make more variables `let` and use `Mutex.synchronize` instead of `Mutex.lock()+unlock()` in a few more cases for consistency
Tim Burks 7 years ago
parent
commit
7fb21c81d5

+ 1 - 1
Sources/gRPC/ByteBuffer.swift

@@ -21,7 +21,7 @@ import Foundation // for String.Encoding
 /// Representation of raw data that may be sent and received using gRPC
 /// Representation of raw data that may be sent and received using gRPC
 public class ByteBuffer {
 public class ByteBuffer {
   /// Pointer to underlying C representation
   /// Pointer to underlying C representation
-  var underlyingByteBuffer: UnsafeMutableRawPointer
+  let underlyingByteBuffer: UnsafeMutableRawPointer
 
 
   /// Creates a ByteBuffer from an underlying C representation.
   /// Creates a ByteBuffer from an underlying C representation.
   /// The ByteBuffer takes ownership of the passed-in representation.
   /// The ByteBuffer takes ownership of the passed-in representation.

+ 23 - 23
Sources/gRPC/Call.swift

@@ -86,11 +86,11 @@ public enum CallError: Error {
 }
 }
 
 
 public struct CallResult: CustomStringConvertible {
 public struct CallResult: CustomStringConvertible {
-  public var statusCode: StatusCode
-  public var statusMessage: String?
-  public var resultData: Data?
-  public var initialMetadata: Metadata?
-  public var trailingMetadata: Metadata?
+  public let statusCode: StatusCode
+  public let statusMessage: String?
+  public let resultData: Data?
+  public let initialMetadata: Metadata?
+  public let trailingMetadata: Metadata?
 
 
   fileprivate init(_ op: OperationGroup) {
   fileprivate init(_ op: OperationGroup) {
     if op.success {
     if op.success {
@@ -146,13 +146,13 @@ public class Call {
   public static var messageQueueMaxLength = 0
   public static var messageQueueMaxLength = 0
 
 
   /// Pointer to underlying C representation
   /// Pointer to underlying C representation
-  private var underlyingCall: UnsafeMutableRawPointer
+  private let underlyingCall: UnsafeMutableRawPointer
 
 
   /// Completion queue used for call
   /// Completion queue used for call
-  private var completionQueue: CompletionQueue
+  private let completionQueue: CompletionQueue
 
 
   /// True if this instance is responsible for deleting the underlying C representation
   /// True if this instance is responsible for deleting the underlying C representation
-  private var owned: Bool
+  private let owned: Bool
 
 
   /// A queue of pending messages to send over the call
   /// A queue of pending messages to send over the call
   private var messageQueue: Array<Data>
   private var messageQueue: Array<Data>
@@ -161,10 +161,10 @@ public class Call {
   private var writing: Bool
   private var writing: Bool
 
 
   /// Mutex for synchronizing message sending
   /// Mutex for synchronizing message sending
-  private var sendMutex: Mutex
+  private let sendMutex: Mutex
 
 
   /// Dispatch queue used for sending messages asynchronously
   /// Dispatch queue used for sending messages asynchronously
-  private var messageDispatchQueue: DispatchQueue = DispatchQueue.global()
+  private let messageDispatchQueue: DispatchQueue = DispatchQueue.global()
 
 
   /// Initializes a Call representation
   /// Initializes a Call representation
   ///
   ///
@@ -251,17 +251,17 @@ public class Call {
   /// Parameter data: the message data to send
   /// Parameter data: the message data to send
   /// - Throws: `CallError` if fails to call. `CallWarning` if blocked.
   /// - Throws: `CallError` if fails to call. `CallWarning` if blocked.
   public func sendMessage(data: Data, errorHandler: @escaping (Error) -> Void) throws {
   public func sendMessage(data: Data, errorHandler: @escaping (Error) -> Void) throws {
-    sendMutex.lock()
-    defer { self.sendMutex.unlock() }
-    if writing {
-      if (Call.messageQueueMaxLength > 0) && // if max length is <= 0, consider it infinite
-        (messageQueue.count == Call.messageQueueMaxLength) {
-        throw CallWarning.blocked
+    try sendMutex.synchronize {
+      if writing {
+        if (Call.messageQueueMaxLength > 0) && // if max length is <= 0, consider it infinite
+          (messageQueue.count == Call.messageQueueMaxLength) {
+          throw CallWarning.blocked
+        }
+        messageQueue.append(data)
+      } else {
+        writing = true
+        try sendWithoutBlocking(data: data, errorHandler: errorHandler)
       }
       }
-      messageQueue.append(data)
-    } else {
-      writing = true
-      try sendWithoutBlocking(data: data, errorHandler: errorHandler)
     }
     }
   }
   }
 
 
@@ -323,8 +323,8 @@ public class Call {
   /// Finishes the request side of this call, notifies the server that the RPC should be cancelled,
   /// Finishes the request side of this call, notifies the server that the RPC should be cancelled,
   /// and finishes the response side of the call with an error of code CANCELED.
   /// and finishes the response side of the call with an error of code CANCELED.
   public func cancel() {
   public func cancel() {
-    Call.callMutex.lock()
-    cgrpc_call_cancel(underlyingCall)
-    Call.callMutex.unlock()
+    Call.callMutex.synchronize {
+      cgrpc_call_cancel(underlyingCall)
+    }
   }
   }
 }
 }

+ 6 - 6
Sources/gRPC/Channel.swift

@@ -21,10 +21,10 @@ import Foundation
 /// A gRPC Channel
 /// A gRPC Channel
 public class Channel {
 public class Channel {
   /// Pointer to underlying C representation
   /// Pointer to underlying C representation
-  private var underlyingChannel: UnsafeMutableRawPointer
+  private let underlyingChannel: UnsafeMutableRawPointer
 
 
   /// Completion queue for channel call operations
   /// Completion queue for channel call operations
-  private var completionQueue: CompletionQueue
+  private let completionQueue: CompletionQueue
 
 
   /// Timeout for new calls
   /// Timeout for new calls
   public var timeout: TimeInterval = 600.0
   public var timeout: TimeInterval = 600.0
@@ -43,8 +43,8 @@ public class Channel {
     } else {
     } else {
       underlyingChannel = cgrpc_channel_create(address)
       underlyingChannel = cgrpc_channel_create(address)
     }
     }
-    completionQueue = CompletionQueue(underlyingCompletionQueue: cgrpc_channel_completion_queue(underlyingChannel))
-    completionQueue.name = "Client" // only for debugging
+    completionQueue = CompletionQueue(
+      underlyingCompletionQueue: cgrpc_channel_completion_queue(underlyingChannel), name: "Client")
     completionQueue.run() // start a loop that watches the channel's completion queue
     completionQueue.run() // start a loop that watches the channel's completion queue
   }
   }
 
 
@@ -56,8 +56,8 @@ public class Channel {
   public init(address: String, certificates: String, host: String?) {
   public init(address: String, certificates: String, host: String?) {
     self.host = address
     self.host = address
     underlyingChannel = cgrpc_channel_create_secure(address, certificates, host)
     underlyingChannel = cgrpc_channel_create_secure(address, certificates, host)
-    completionQueue = CompletionQueue(underlyingCompletionQueue: cgrpc_channel_completion_queue(underlyingChannel))
-    completionQueue.name = "Client" // only for debugging
+    completionQueue = CompletionQueue(
+      underlyingCompletionQueue: cgrpc_channel_completion_queue(underlyingChannel), name: "Client")
     completionQueue.run() // start a loop that watches the channel's completion queue
     completionQueue.run() // start a loop that watches the channel's completion queue
   }
   }
 
 

+ 17 - 16
Sources/gRPC/CompletionQueue.swift

@@ -42,9 +42,9 @@ enum CompletionType {
 
 
 /// An event that is returned by the completion queue
 /// An event that is returned by the completion queue
 struct CompletionQueueEvent {
 struct CompletionQueueEvent {
-  var type: CompletionType
-  var success: Int32
-  var tag: Int64
+  let type: CompletionType
+  let success: Int32
+  let tag: Int64
 
 
   init(_ event: grpc_event) {
   init(_ event: grpc_event) {
     type = CompletionType.completionType(event.type)
     type = CompletionType.completionType(event.type)
@@ -56,23 +56,24 @@ struct CompletionQueueEvent {
 /// A gRPC Completion Queue
 /// A gRPC Completion Queue
 class CompletionQueue {
 class CompletionQueue {
   /// Optional user-provided name for the queue
   /// Optional user-provided name for the queue
-  var name: String?
+  let name: String?
 
 
   /// Pointer to underlying C representation
   /// Pointer to underlying C representation
-  private var underlyingCompletionQueue: UnsafeMutableRawPointer
+  private let underlyingCompletionQueue: UnsafeMutableRawPointer
 
 
   /// Operation groups that are awaiting completion, keyed by tag
   /// Operation groups that are awaiting completion, keyed by tag
   private var operationGroups: [Int64: OperationGroup] = [:]
   private var operationGroups: [Int64: OperationGroup] = [:]
 
 
   /// Mutex for synchronizing access to operationGroups
   /// Mutex for synchronizing access to operationGroups
-  private var operationGroupsMutex: Mutex = Mutex()
+  private let operationGroupsMutex: Mutex = Mutex()
 
 
   /// Initializes a CompletionQueue
   /// Initializes a CompletionQueue
   ///
   ///
   /// - Parameter cq: the underlying C representation
   /// - Parameter cq: the underlying C representation
-  init(underlyingCompletionQueue: UnsafeMutableRawPointer) {
+  init(underlyingCompletionQueue: UnsafeMutableRawPointer, name: String? = nil) {
     // The underlying completion queue is NOT OWNED by this class, so we don't dealloc it in a deinit
     // The underlying completion queue is NOT OWNED by this class, so we don't dealloc it in a deinit
     self.underlyingCompletionQueue = underlyingCompletionQueue
     self.underlyingCompletionQueue = underlyingCompletionQueue
+    self.name = name
   }
   }
 
 
   /// Waits for an operation group to complete
   /// Waits for an operation group to complete
@@ -88,9 +89,9 @@ class CompletionQueue {
   ///
   ///
   /// - Parameter operationGroup: the operation group to handle
   /// - Parameter operationGroup: the operation group to handle
   func register(_ operationGroup: OperationGroup) {
   func register(_ operationGroup: OperationGroup) {
-    operationGroupsMutex.lock()
-    operationGroups[operationGroup.tag] = operationGroup
-    operationGroupsMutex.unlock()
+    operationGroupsMutex.synchronize {
+      operationGroups[operationGroup.tag] = operationGroup
+    }
   }
   }
 
 
   /// Runs a completion queue and call a completion handler when finished
   /// Runs a completion queue and call a completion handler when finished
@@ -118,9 +119,9 @@ class CompletionQueue {
             } catch (let callError) {
             } catch (let callError) {
               print("CompletionQueue runToCompletion: grpc error \(callError)")
               print("CompletionQueue runToCompletion: grpc error \(callError)")
             }
             }
-            self.operationGroupsMutex.lock()
-            self.operationGroups[tag] = nil
-            self.operationGroupsMutex.unlock()
+            self.operationGroupsMutex.synchronize {
+              self.operationGroups[tag] = nil
+            }
           }
           }
           break
           break
         case GRPC_QUEUE_SHUTDOWN:
         case GRPC_QUEUE_SHUTDOWN:
@@ -133,9 +134,9 @@ class CompletionQueue {
           } catch (let callError) {
           } catch (let callError) {
             print("CompletionQueue runToCompletion: grpc error \(callError)")
             print("CompletionQueue runToCompletion: grpc error \(callError)")
           }
           }
-          self.operationGroupsMutex.lock()
-          self.operationGroups = [:]
-          self.operationGroupsMutex.unlock()
+          self.operationGroupsMutex.synchronize {
+            self.operationGroups = [:]
+          }
           break
           break
         case GRPC_QUEUE_TIMEOUT:
         case GRPC_QUEUE_TIMEOUT:
           break
           break

+ 2 - 2
Sources/gRPC/Handler.swift

@@ -65,8 +65,8 @@ public class Handler {
   init(underlyingServer: UnsafeMutableRawPointer) {
   init(underlyingServer: UnsafeMutableRawPointer) {
     underlyingHandler = cgrpc_handler_create_with_server(underlyingServer)
     underlyingHandler = cgrpc_handler_create_with_server(underlyingServer)
     requestMetadata = Metadata()
     requestMetadata = Metadata()
-    completionQueue = CompletionQueue(underlyingCompletionQueue: cgrpc_handler_get_completion_queue(underlyingHandler))
-    completionQueue.name = "Handler"
+    completionQueue = CompletionQueue(
+      underlyingCompletionQueue: cgrpc_handler_get_completion_queue(underlyingHandler), name: "Handler")
   }
   }
 
 
   deinit {
   deinit {

+ 1 - 1
Sources/gRPC/Metadata.swift

@@ -21,7 +21,7 @@ import Foundation // for String.Encoding
 /// Metadata sent with gRPC messages
 /// Metadata sent with gRPC messages
 public class Metadata: CustomStringConvertible {
 public class Metadata: CustomStringConvertible {
   /// Pointer to underlying C representation
   /// Pointer to underlying C representation
-  var underlyingArray: UnsafeMutableRawPointer
+  let underlyingArray: UnsafeMutableRawPointer
 
 
   init(underlyingArray: UnsafeMutableRawPointer) {
   init(underlyingArray: UnsafeMutableRawPointer) {
     self.underlyingArray = underlyingArray
     self.underlyingArray = underlyingArray

+ 3 - 3
Sources/gRPC/Mutex.swift

@@ -21,7 +21,7 @@
 /// but it can be used anywhere
 /// but it can be used anywhere
 public class Mutex {
 public class Mutex {
   /// Pointer to underlying C representation
   /// Pointer to underlying C representation
-  private var underlyingMutex: UnsafeMutableRawPointer
+  private let underlyingMutex: UnsafeMutableRawPointer
 
 
   /// Initializes a Mutex
   /// Initializes a Mutex
   public init() {
   public init() {
@@ -53,9 +53,9 @@ public class Mutex {
   /// Runs a block within a locked mutex
   /// Runs a block within a locked mutex
   ///
   ///
   /// Parameter block: the code to run while the mutex is locked
   /// Parameter block: the code to run while the mutex is locked
-  public func synchronize(block: () -> Void) {
+  public func synchronize(block: () throws -> Void) rethrows {
     lock()
     lock()
-    block()
+    try block()
     unlock()
     unlock()
   }
   }
 }
 }

+ 7 - 7
Sources/gRPC/OperationGroup.swift

@@ -26,32 +26,32 @@ class OperationGroup {
   private static var nextTag: Int64 = 1
   private static var nextTag: Int64 = 1
 
 
   /// Automatically-assigned tag that is used by the completion queue that watches this group.
   /// Automatically-assigned tag that is used by the completion queue that watches this group.
-  var tag: Int64
+  let tag: Int64
 
 
   /// The call associated with the operation group. Retained while the operations are running.
   /// The call associated with the operation group. Retained while the operations are running.
-  private var call: Call
+  private let call: Call
 
 
   /// An array of operation objects that are passed into the initializer.
   /// An array of operation objects that are passed into the initializer.
-  private var operations: [Operation]
+  private let operations: [Operation]
 
 
   /// An array of observers used to watch the operation
   /// An array of observers used to watch the operation
   private var underlyingObservers: [UnsafeMutableRawPointer] = []
   private var underlyingObservers: [UnsafeMutableRawPointer] = []
 
 
   /// Pointer to underlying C representation
   /// Pointer to underlying C representation
-  var underlyingOperations: UnsafeMutableRawPointer?
+  let underlyingOperations: UnsafeMutableRawPointer?
 
 
   /// Completion handler that is called when the group completes
   /// Completion handler that is called when the group completes
-  var completion: ((OperationGroup) throws -> Void)
+  let completion: ((OperationGroup) throws -> Void)
 
 
   /// Indicates that the OperationGroup completed successfully
   /// Indicates that the OperationGroup completed successfully
-  var success: Bool = false
+  var success = false
 
 
   /// Creates the underlying observer needed to run an operation
   /// Creates the underlying observer needed to run an operation
   ///
   ///
   /// - Parameter: operation: the operation to observe
   /// - Parameter: operation: the operation to observe
   /// - Returns: the observer
   /// - Returns: the observer
   private func underlyingObserverForOperation(operation: Operation) -> UnsafeMutableRawPointer {
   private func underlyingObserverForOperation(operation: Operation) -> UnsafeMutableRawPointer {
-    var underlyingObserver: UnsafeMutableRawPointer
+    let underlyingObserver: UnsafeMutableRawPointer
     switch operation {
     switch operation {
     case .sendInitialMetadata(let metadata):
     case .sendInitialMetadata(let metadata):
       underlyingObserver = cgrpc_observer_create_send_initial_metadata(metadata.underlyingArray)!
       underlyingObserver = cgrpc_observer_create_send_initial_metadata(metadata.underlyingArray)!

+ 4 - 4
Sources/gRPC/Server.swift

@@ -41,8 +41,8 @@ public class Server {
   /// - Parameter address: the address where the server will listen
   /// - Parameter address: the address where the server will listen
   public init(address: String) {
   public init(address: String) {
     underlyingServer = cgrpc_server_create(address)
     underlyingServer = cgrpc_server_create(address)
-    completionQueue = CompletionQueue(underlyingCompletionQueue: cgrpc_server_get_completion_queue(underlyingServer))
-    completionQueue.name = "Server " + address
+    completionQueue = CompletionQueue(
+      underlyingCompletionQueue: cgrpc_server_get_completion_queue(underlyingServer), name: "Server " + address)
   }
   }
 
 
   /// Initializes a secure Server
   /// Initializes a secure Server
@@ -52,8 +52,8 @@ public class Server {
   /// - Parameter certs: the server's certificates
   /// - Parameter certs: the server's certificates
   public init(address: String, key: String, certs: String) {
   public init(address: String, key: String, certs: String) {
     underlyingServer = cgrpc_server_create_secure(address, key, certs)
     underlyingServer = cgrpc_server_create_secure(address, key, certs)
-    completionQueue = CompletionQueue(underlyingCompletionQueue: cgrpc_server_get_completion_queue(underlyingServer))
-    completionQueue.name = "Server " + address
+    completionQueue = CompletionQueue(
+      underlyingCompletionQueue: cgrpc_server_get_completion_queue(underlyingServer), name: "Server " + address)
   }
   }
 
 
   deinit {
   deinit {