@@ -101,7 +101,7 @@ abstract class Channel[T] extends ReadChannel[T] with WriteChannel[T] {
101
101
102
102
protected def fetchValueOpt (): Option [T ]
103
103
104
- final override def sender (value : T ) (action : => Unit = {}): Selector = {
104
+ final override def sender (value : T )(action : => Unit = {}): Selector = {
105
105
new Selector (true , this ) {
106
106
override def sendRecv (): Boolean = trySend(value)
107
107
@@ -250,23 +250,23 @@ object Channel {
250
250
val CLOSED = 2
251
251
252
252
/**
253
- * Create a synchronous channel.
254
- *
255
- * @tparam T The type of the channel.
256
- * @return A new channel
257
- */
253
+ * Create a synchronous channel.
254
+ *
255
+ * @tparam T The type of the channel.
256
+ * @return A new channel
257
+ */
258
258
def make [T ]: Channel [T ] = {
259
259
new SyncChannel [T ]
260
260
}
261
261
262
262
/**
263
- * Create a channel. By default a synchronous channel will be created.
264
- * If bufferSize is greater then zero, a buffered channel will be created.
265
- *
266
- * @param bufferSize Asynchronous buffer size.
267
- * @tparam T The type of the channel.
268
- * @return A new channel
269
- */
263
+ * Create a channel. By default a synchronous channel will be created.
264
+ * If bufferSize is greater then zero, a buffered channel will be created.
265
+ *
266
+ * @param bufferSize Asynchronous buffer size.
267
+ * @tparam T The type of the channel.
268
+ * @return A new channel
269
+ */
270
270
def make [T ](bufferSize : Int ): Channel [T ] = {
271
271
require(bufferSize >= 0 )
272
272
@@ -288,41 +288,86 @@ object Channel {
288
288
}
289
289
290
290
/**
291
- * Waits for a non-blocking operation to be available on the list of channels.
292
- *
293
- * @param selector A first channel to wait for (mandatory).
294
- * @param selectors Other channels to wait for.
295
- * @return true is none of the channels are closed and select() can be invoked again, false if at least one of channels is closed.
296
- */
291
+ * Waits for a non-blocking operation to be available on the list of channels.
292
+ * If more than one channel is ready to perform its operation, the channel to perform the operation on will be chosen
293
+ * at random.
294
+ *
295
+ * @param selector A first channel to wait for (mandatory).
296
+ * @param selectors Other channels to wait for.
297
+ * @return true is none of the channels are closed and select() can be invoked again, false if at least one of channels is closed.
298
+ */
297
299
def select (selector : Selector , selectors : Selector * ): Boolean = {
298
- trySelect(Duration .Inf , selector, selectors : _* )
300
+ trySelect(Duration .Inf , false , selector, selectors : _* )
301
+ }
302
+
303
+ /**
304
+ * Waits for a non-blocking operation to be available on the list of channels.
305
+ * If more than one channel is ready to perform its operation, the first one in the list takes precedence.
306
+ *
307
+ * @param selector A first channel to wait for (mandatory).
308
+ * @param selectors Other channels to wait for.
309
+ * @return true is none of the channels are closed and select() can be invoked again, false if at least one of channels is closed.
310
+ */
311
+ def prioritySelect (selector : Selector , selectors : Selector * ): Boolean = {
312
+ trySelect(Duration .Inf , true , selector, selectors : _* )
299
313
}
300
314
301
315
/**
302
- * Non-blocking check for a possibility of a non-blocking operation on several channels.
303
- *
304
- * @param selector A first channel to wait for (mandatory).
305
- * @param selectors Other channels to wait for.
306
- * @return true if one of pending operations wasn't blocking.
307
- */
316
+ * Non-blocking check for a possibility of a non-blocking operation on several channels.
317
+ * If more than one channel is ready to perform its operation, the channel to perform the operation on will be chosen
318
+ * at random.
319
+ *
320
+ * @param selector A first channel to wait for (mandatory).
321
+ * @param selectors Other channels to wait for.
322
+ * @return true if one of pending operations wasn't blocking.
323
+ */
308
324
def trySelect (selector : Selector , selectors : Selector * ): Boolean = {
309
- trySelect(Duration .Zero , selector, selectors : _* )
325
+ trySelect(Duration .Zero , false , selector, selectors : _* )
310
326
}
311
327
312
328
/**
313
- * Waits for a non-bloaking action to be available.
314
- *
315
- * @param timout A timeout to wait for a non-blocking action to be available.
316
- * @param selector A first channel to wait for (mandatory).
317
- * @param selectors Other channels to wait for.
318
- * @return true if one of pending operations wasn't blockingю
319
- */
320
- @ throws[InterruptedException ]
329
+ * Non-blocking check for a possibility of a non-blocking operation on several channels.
330
+ *
331
+ * @param selector A first channel to wait for (mandatory).
332
+ * @param selectors Other channels to wait for.
333
+ * @return true if one of pending operations wasn't blocking.
334
+ */
321
335
def trySelect (timout : Duration , selector : Selector , selectors : Selector * ): Boolean = {
336
+ trySelect(timout, false , selector, selectors : _* )
337
+ }
338
+
339
+ /**
340
+ * Non-blocking check for a possibility of a non-blocking operation on several channels.
341
+ * If more than one channel is ready to perform its operation, the first one in the list takes precedence.
342
+ *
343
+ * @param selector A first channel to wait for (mandatory).
344
+ * @param selectors Other channels to wait for.
345
+ * @return true if one of pending operations wasn't blocking.
346
+ */
347
+ def tryPrioritySelect (selector : Selector , selectors : Selector * ): Boolean = {
348
+ trySelect(Duration .Zero , true , selector, selectors : _* )
349
+ }
350
+
351
+ /**
352
+ * Waits for a non-bloaking action to be available.
353
+ *
354
+ * @param timout A timeout to wait for a non-blocking action to be available.
355
+ * @param isPriorityOrdered If true, when more then one selectors is ready, the first one in the list will be selected.
356
+ * @param selector A first channel to wait for (mandatory).
357
+ * @param selectors Other channels to wait for.
358
+ * @return true if one of pending operations wasn't blockingю
359
+ */
360
+ @ throws[InterruptedException ]
361
+ def trySelect (timout : Duration , isPriorityOrdered : Boolean , selector : Selector , selectors : Selector * ): Boolean = {
322
362
val sem = new Semaphore (0 )
323
363
324
- // If several channels have pending messages, select randomly the channel to return
325
- val sel = scala.util.Random .shuffle(selector :: selectors.toList).toArray
364
+ val sel = if (isPriorityOrdered) {
365
+ // If channels are ordered by priority, retain the original order
366
+ (selector :: selectors.toList).toArray
367
+ } else {
368
+ // If several channels have pending messages, select randomly the channel to return
369
+ scala.util.Random .shuffle(selector :: selectors.toList).toArray
370
+ }
326
371
327
372
// Add waiters
328
373
var i = 0
0 commit comments