@@ -101,7 +101,7 @@ abstract class Channel[T] extends ReadChannel[T] with WriteChannel[T] {
101101
102102 protected def fetchValueOpt (): Option [T ]
103103
104- final override def sender (value : T ) (action : => Unit = {}): Selector = {
104+ final override def sender (value : T )(action : => Unit = {}): Selector = {
105105 new Selector (true , this ) {
106106 override def sendRecv (): Boolean = trySend(value)
107107
@@ -250,23 +250,23 @@ object Channel {
250250 val CLOSED = 2
251251
252252 /**
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+ */
258258 def make [T ]: Channel [T ] = {
259259 new SyncChannel [T ]
260260 }
261261
262262 /**
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+ */
270270 def make [T ](bufferSize : Int ): Channel [T ] = {
271271 require(bufferSize >= 0 )
272272
@@ -288,41 +288,86 @@ object Channel {
288288 }
289289
290290 /**
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+ */
297299 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 : _* )
299313 }
300314
301315 /**
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+ */
308324 def trySelect (selector : Selector , selectors : Selector * ): Boolean = {
309- trySelect(Duration .Zero , selector, selectors : _* )
325+ trySelect(Duration .Zero , false , selector, selectors : _* )
310326 }
311327
312328 /**
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+ */
321335 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 = {
322362 val sem = new Semaphore (0 )
323363
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+ }
326371
327372 // Add waiters
328373 var i = 0
0 commit comments