summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bincompat-backward.whitelist.conf9
-rw-r--r--bincompat-forward.whitelist.conf97
-rw-r--r--build-ant-macros.xml21
-rw-r--r--build.number4
-rw-r--r--build.sbt13
-rwxr-xr-xbuild.xml111
-rw-r--r--dbuild-meta.json112
-rwxr-xr-xscripts/jobs/integrate/bootstrap60
-rwxr-xr-xscripts/jobs/integrate/ide3
-rw-r--r--src/actors/scala/actors/AbstractActor.scala30
-rw-r--r--src/actors/scala/actors/Actor.scala411
-rw-r--r--src/actors/scala/actors/ActorCanReply.scala66
-rw-r--r--src/actors/scala/actors/ActorProxy.scala34
-rw-r--r--src/actors/scala/actors/ActorRef.scala53
-rw-r--r--src/actors/scala/actors/ActorTask.scala60
-rw-r--r--src/actors/scala/actors/CanReply.scala65
-rw-r--r--src/actors/scala/actors/Channel.scala136
-rw-r--r--src/actors/scala/actors/Combinators.scala48
-rw-r--r--src/actors/scala/actors/DaemonActor.scala24
-rw-r--r--src/actors/scala/actors/Debug.scala45
-rw-r--r--src/actors/scala/actors/Future.scala243
-rw-r--r--src/actors/scala/actors/IScheduler.scala70
-rw-r--r--src/actors/scala/actors/InputChannel.scala66
-rw-r--r--src/actors/scala/actors/InternalActor.scala546
-rw-r--r--src/actors/scala/actors/InternalReplyReactor.scala162
-rw-r--r--src/actors/scala/actors/KillActorControl.scala14
-rw-r--r--src/actors/scala/actors/LinkedNode.java25
-rw-r--r--src/actors/scala/actors/LinkedQueue.java185
-rw-r--r--src/actors/scala/actors/MQueue.scala250
-rw-r--r--src/actors/scala/actors/OutputChannel.scala48
-rw-r--r--src/actors/scala/actors/ReactChannel.scala121
-rw-r--r--src/actors/scala/actors/Reactor.scala307
-rw-r--r--src/actors/scala/actors/ReactorCanReply.scala90
-rw-r--r--src/actors/scala/actors/ReactorTask.scala74
-rw-r--r--src/actors/scala/actors/ReplyReactor.scala13
-rw-r--r--src/actors/scala/actors/ReplyReactorTask.scala40
-rw-r--r--src/actors/scala/actors/Scheduler.scala40
-rw-r--r--src/actors/scala/actors/SchedulerAdapter.scala68
-rw-r--r--src/actors/scala/actors/UncaughtException.scala34
-rw-r--r--src/actors/scala/actors/package.scala23
-rw-r--r--src/actors/scala/actors/remote/FreshNameCreator.scala36
-rw-r--r--src/actors/scala/actors/remote/JavaSerializer.scala63
-rw-r--r--src/actors/scala/actors/remote/NetKernel.scala147
-rw-r--r--src/actors/scala/actors/remote/Proxy.scala190
-rw-r--r--src/actors/scala/actors/remote/RemoteActor.scala132
-rw-r--r--src/actors/scala/actors/remote/Serializer.scala58
-rw-r--r--src/actors/scala/actors/remote/Service.scala24
-rw-r--r--src/actors/scala/actors/remote/TcpService.scala292
-rw-r--r--src/actors/scala/actors/scheduler/ActorGC.scala101
-rw-r--r--src/actors/scala/actors/scheduler/DaemonScheduler.scala34
-rw-r--r--src/actors/scala/actors/scheduler/DelegatingScheduler.scala74
-rw-r--r--src/actors/scala/actors/scheduler/DrainableForkJoinPool.scala11
-rw-r--r--src/actors/scala/actors/scheduler/ExecutorScheduler.scala95
-rw-r--r--src/actors/scala/actors/scheduler/ForkJoinScheduler.scala174
-rw-r--r--src/actors/scala/actors/scheduler/QuitControl.scala19
-rw-r--r--src/actors/scala/actors/scheduler/ResizableThreadPoolScheduler.scala197
-rw-r--r--src/actors/scala/actors/scheduler/SingleThreadedScheduler.scala69
-rw-r--r--src/actors/scala/actors/scheduler/TerminationMonitor.scala69
-rw-r--r--src/actors/scala/actors/scheduler/TerminationService.scala68
-rw-r--r--src/actors/scala/actors/scheduler/ThreadPoolConfig.scala50
-rw-r--r--src/actors/scala/actors/threadpool/AbstractCollection.java32
-rw-r--r--src/actors/scala/actors/threadpool/AbstractExecutorService.java292
-rw-r--r--src/actors/scala/actors/threadpool/AbstractQueue.java170
-rw-r--r--src/actors/scala/actors/threadpool/Arrays.java811
-rw-r--r--src/actors/scala/actors/threadpool/AtomicInteger.java210
-rw-r--r--src/actors/scala/actors/threadpool/BlockingQueue.java344
-rw-r--r--src/actors/scala/actors/threadpool/Callable.java35
-rw-r--r--src/actors/scala/actors/threadpool/CancellationException.java34
-rw-r--r--src/actors/scala/actors/threadpool/CompletionService.java97
-rw-r--r--src/actors/scala/actors/threadpool/ExecutionException.java65
-rw-r--r--src/actors/scala/actors/threadpool/Executor.java112
-rw-r--r--src/actors/scala/actors/threadpool/ExecutorCompletionService.java178
-rw-r--r--src/actors/scala/actors/threadpool/ExecutorService.java331
-rw-r--r--src/actors/scala/actors/threadpool/Executors.java667
-rw-r--r--src/actors/scala/actors/threadpool/Future.java142
-rw-r--r--src/actors/scala/actors/threadpool/FutureTask.java310
-rw-r--r--src/actors/scala/actors/threadpool/LinkedBlockingQueue.java843
-rw-r--r--src/actors/scala/actors/threadpool/Perf.java28
-rw-r--r--src/actors/scala/actors/threadpool/Queue.java191
-rw-r--r--src/actors/scala/actors/threadpool/RejectedExecutionException.java62
-rw-r--r--src/actors/scala/actors/threadpool/RejectedExecutionHandler.java34
-rw-r--r--src/actors/scala/actors/threadpool/RunnableFuture.java24
-rw-r--r--src/actors/scala/actors/threadpool/SynchronousQueue.java833
-rw-r--r--src/actors/scala/actors/threadpool/ThreadFactory.java41
-rw-r--r--src/actors/scala/actors/threadpool/ThreadPoolExecutor.java1968
-rw-r--r--src/actors/scala/actors/threadpool/TimeUnit.java407
-rw-r--r--src/actors/scala/actors/threadpool/TimeoutException.java38
-rw-r--r--src/actors/scala/actors/threadpool/helpers/FIFOWaitQueue.java85
-rw-r--r--src/actors/scala/actors/threadpool/helpers/NanoTimer.java29
-rw-r--r--src/actors/scala/actors/threadpool/helpers/ThreadHelpers.java66
-rw-r--r--src/actors/scala/actors/threadpool/helpers/Utils.java343
-rw-r--r--src/actors/scala/actors/threadpool/helpers/WaitQueue.java146
-rw-r--r--src/actors/scala/actors/threadpool/locks/CondVar.java191
-rw-r--r--src/actors/scala/actors/threadpool/locks/Condition.java434
-rw-r--r--src/actors/scala/actors/threadpool/locks/FIFOCondVar.java147
-rw-r--r--src/actors/scala/actors/threadpool/locks/Lock.java328
-rw-r--r--src/actors/scala/actors/threadpool/locks/ReadWriteLock.java104
-rw-r--r--src/actors/scala/actors/threadpool/locks/ReentrantLock.java959
-rw-r--r--src/actors/scala/actors/threadpool/locks/ReentrantReadWriteLock.java1341
-rw-r--r--src/build/bnd/scala-actors.bnd7
-rw-r--r--src/build/bnd/scala-continuations-library.bnd7
-rw-r--r--src/build/bnd/scala-continuations-plugin.bnd7
-rw-r--r--src/build/dbuild-meta-json-gen.scala27
-rw-r--r--src/build/maven/scala-actors-pom.xml51
-rw-r--r--src/build/maven/scala-dist-pom.xml6
-rw-r--r--src/build/maven/scala-library-all-pom.xml20
-rw-r--r--src/compiler/scala/tools/cmd/Property.scala3
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala7
-rwxr-xr-xsrc/compiler/scala/tools/nsc/ast/DocComments.scala19
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala22
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala4
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala6
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala3
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala3
-rw-r--r--src/compiler/scala/tools/nsc/settings/AbsScalaSettings.scala1
-rw-r--r--src/compiler/scala/tools/nsc/settings/MutableSettings.scala7
-rw-r--r--src/compiler/scala/tools/nsc/settings/ScalaVersion.scala50
-rw-r--r--src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/Delambdafy.scala9
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala6
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala20
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala72
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala15
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala104
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala33
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala29
-rw-r--r--src/compiler/scala/tools/reflect/WrappedProperties.scala5
-rw-r--r--src/compiler/scala/tools/util/PathResolver.scala2
-rw-r--r--src/eclipse/partest/.classpath2
-rw-r--r--src/eclipse/repl/.classpath1
-rw-r--r--src/eclipse/scaladoc/.classpath6
-rw-r--r--src/forkjoin/scala/concurrent/forkjoin/ForkJoinPool.java3
-rw-r--r--src/forkjoin/scala/concurrent/forkjoin/ForkJoinTask.java5
-rw-r--r--src/forkjoin/scala/concurrent/forkjoin/ForkJoinWorkerThread.java1
-rw-r--r--src/forkjoin/scala/concurrent/forkjoin/LinkedTransferQueue.java3
-rw-r--r--src/forkjoin/scala/concurrent/forkjoin/RecursiveAction.java1
-rw-r--r--src/forkjoin/scala/concurrent/forkjoin/RecursiveTask.java1
-rw-r--r--src/forkjoin/scala/concurrent/forkjoin/ThreadLocalRandom.java2
-rw-r--r--src/forkjoin/scala/concurrent/forkjoin/TransferQueue.java1
-rw-r--r--src/forkjoin/scala/concurrent/util/Unsafe.java6
-rw-r--r--src/intellij/actors.iml.SAMPLE14
-rw-r--r--src/intellij/scala.ipr.SAMPLE1
-rw-r--r--src/intellij/test-junit.iml.SAMPLE1
-rw-r--r--src/intellij/test.iml.SAMPLE1
-rw-r--r--src/interactive/scala/tools/nsc/interactive/Global.scala27
-rw-r--r--src/library/rootdoc.txt4
-rw-r--r--src/library/scala/PartialFunction.scala4
-rw-r--r--src/library/scala/Predef.scala34
-rw-r--r--src/library/scala/beans/BeanInfo.scala1
-rw-r--r--src/library/scala/collection/IterableViewLike.scala5
-rw-r--r--src/library/scala/collection/Iterator.scala123
-rw-r--r--src/library/scala/collection/MapLike.scala21
-rw-r--r--src/library/scala/collection/SeqViewLike.scala22
-rw-r--r--src/library/scala/collection/SetLike.scala15
-rw-r--r--src/library/scala/collection/TraversableLike.scala2
-rw-r--r--src/library/scala/collection/TraversableViewLike.scala22
-rw-r--r--src/library/scala/collection/concurrent/Map.scala11
-rw-r--r--src/library/scala/collection/convert/WrapAsJava.scala56
-rw-r--r--src/library/scala/collection/convert/WrapAsScala.scala35
-rw-r--r--src/library/scala/collection/immutable/HashSet.scala30
-rw-r--r--src/library/scala/collection/immutable/List.scala4
-rw-r--r--src/library/scala/collection/immutable/ListMap.scala19
-rw-r--r--src/library/scala/collection/immutable/Map.scala22
-rw-r--r--src/library/scala/collection/immutable/PagedSeq.scala2
-rw-r--r--src/library/scala/collection/immutable/Range.scala19
-rw-r--r--src/library/scala/collection/immutable/Stream.scala103
-rw-r--r--src/library/scala/collection/immutable/StreamViewLike.scala2
-rw-r--r--src/library/scala/collection/mutable/AnyRefMap.scala18
-rw-r--r--src/library/scala/collection/mutable/ArrayOps.scala5
-rw-r--r--src/library/scala/collection/mutable/ArraySeq.scala2
-rw-r--r--src/library/scala/collection/mutable/BufferLike.scala7
-rw-r--r--src/library/scala/collection/mutable/BufferProxy.scala2
-rw-r--r--src/library/scala/collection/mutable/ListBuffer.scala7
-rw-r--r--src/library/scala/collection/mutable/LongMap.scala20
-rw-r--r--src/library/scala/collection/mutable/MapLike.scala12
-rw-r--r--src/library/scala/collection/mutable/PriorityQueue.scala2
-rw-r--r--src/library/scala/collection/mutable/ResizableArray.scala2
-rw-r--r--src/library/scala/collection/mutable/SetLike.scala11
-rw-r--r--src/library/scala/collection/parallel/RemainsIterator.scala9
-rw-r--r--src/library/scala/collection/parallel/immutable/ParHashSet.scala2
-rw-r--r--src/library/scala/concurrent/BlockContext.scala15
-rw-r--r--src/library/scala/concurrent/ExecutionContext.scala36
-rw-r--r--src/library/scala/concurrent/Future.scala469
-rw-r--r--src/library/scala/concurrent/Promise.scala12
-rw-r--r--src/library/scala/concurrent/duration/Duration.scala2
-rw-r--r--src/library/scala/concurrent/impl/AbstractPromise.java40
-rw-r--r--src/library/scala/concurrent/impl/ExecutionContextImpl.scala208
-rw-r--r--src/library/scala/concurrent/impl/Future.scala34
-rw-r--r--src/library/scala/concurrent/impl/Promise.scala167
-rw-r--r--src/library/scala/deprecatedName.scala4
-rw-r--r--src/library/scala/io/Source.scala4
-rw-r--r--src/library/scala/math/package.scala2
-rw-r--r--src/library/scala/runtime/BoxesRunTime.java2
-rw-r--r--src/library/scala/runtime/ScalaRunTime.scala2
-rw-r--r--src/library/scala/sys/SystemProperties.scala11
-rw-r--r--src/library/scala/sys/process/BasicIO.scala2
-rw-r--r--src/library/scala/sys/process/ProcessImpl.scala134
-rw-r--r--src/library/scala/sys/process/package.scala30
-rw-r--r--src/library/scala/util/Either.scala2
-rw-r--r--src/library/scala/util/Try.scala146
-rw-r--r--src/manual/scala/man1/scalac.scala7
-rw-r--r--src/reflect/scala/reflect/api/Symbols.scala23
-rw-r--r--src/reflect/scala/reflect/internal/Mirrors.scala11
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala1
-rw-r--r--src/reflect/scala/reflect/internal/SymbolTable.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala18
-rw-r--r--src/reflect/scala/reflect/internal/TreeGen.scala4
-rw-r--r--src/reflect/scala/reflect/internal/TreeInfo.scala1
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala20
-rw-r--r--src/reflect/scala/reflect/internal/pickling/UnPickler.scala1
-rw-r--r--src/reflect/scala/reflect/internal/tpe/TypeMaps.scala9
-rw-r--r--src/reflect/scala/reflect/internal/transform/Erasure.scala11
-rwxr-xr-xsrc/scaladoc/scala/tools/nsc/doc/base/MemberLookupBase.scala8
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala24
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala10
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css2
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js20
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/model/MemberLookup.scala2
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala10
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala2
-rwxr-xr-xsrc/scaladoc/scala/tools/nsc/doc/model/TreeFactory.scala2
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala2
-rw-r--r--test/files/filters1
-rw-r--r--test/files/jvm/actor-exceptions.check1
-rw-r--r--test/files/jvm/actor-exceptions.scala67
-rw-r--r--test/files/jvm/actor-executor.check20
-rw-r--r--test/files/jvm/actor-executor.scala78
-rw-r--r--test/files/jvm/actor-executor2.check21
-rw-r--r--test/files/jvm/actor-executor2.scala92
-rw-r--r--test/files/jvm/actor-executor3.check20
-rw-r--r--test/files/jvm/actor-executor3.scala66
-rw-r--r--test/files/jvm/actor-getstate.check2
-rw-r--r--test/files/jvm/actor-getstate.scala87
-rw-r--r--test/files/jvm/actor-link-getstate.check2
-rw-r--r--test/files/jvm/actor-link-getstate.scala65
-rw-r--r--test/files/jvm/actor-looping.check5
-rw-r--r--test/files/jvm/actor-looping.scala33
-rw-r--r--test/files/jvm/actor-normal-exit.check2
-rw-r--r--test/files/jvm/actor-normal-exit.scala38
-rw-r--r--test/files/jvm/actor-receivewithin.check16
-rw-r--r--test/files/jvm/actor-receivewithin.scala72
-rw-r--r--test/files/jvm/actor-sync-send-timeout.scala48
-rw-r--r--test/files/jvm/actor-termination.check2
-rw-r--r--test/files/jvm/actor-termination.scala19
-rw-r--r--test/files/jvm/actor-uncaught-exception.check2
-rw-r--r--test/files/jvm/actor-uncaught-exception.scala64
-rw-r--r--test/files/jvm/actor-uncaught-exception2.check2
-rw-r--r--test/files/jvm/actor-uncaught-exception2.scala63
-rw-r--r--test/files/jvm/daemon-actor-termination.check2
-rw-r--r--test/files/jvm/daemon-actor-termination.scala40
-rw-r--r--test/files/jvm/future-alarm.check20
-rw-r--r--test/files/jvm/future-alarm.scala23
-rw-r--r--test/files/jvm/future-awaitall-zero.check1
-rw-r--r--test/files/jvm/future-awaitall-zero.scala24
-rw-r--r--test/files/jvm/future-spec.check2
-rw-r--r--test/files/jvm/future-spec/FutureTests.scala273
-rw-r--r--test/files/jvm/future-termination.check1
-rw-r--r--test/files/jvm/future-termination.scala21
-rw-r--r--test/files/jvm/reactor-exceptionOnSend.check2
-rw-r--r--test/files/jvm/reactor-exceptionOnSend.scala58
-rw-r--r--test/files/jvm/reactor-producer-consumer.check10
-rw-r--r--test/files/jvm/reactor-producer-consumer.scala97
-rw-r--r--test/files/jvm/reactor.check22
-rw-r--r--test/files/jvm/reactor.scala72
-rw-r--r--test/files/jvm/replyablereactor.check5
-rw-r--r--test/files/jvm/replyablereactor.scala59
-rw-r--r--test/files/jvm/replyablereactor2.check5
-rw-r--r--test/files/jvm/replyablereactor2.scala58
-rw-r--r--test/files/jvm/replyablereactor3.check5
-rw-r--r--test/files/jvm/replyablereactor3.scala57
-rw-r--r--test/files/jvm/replyablereactor4.check5
-rw-r--r--test/files/jvm/replyablereactor4.scala57
-rw-r--r--test/files/jvm/replyreactor-react-sender.check1
-rw-r--r--test/files/jvm/replyreactor-react-sender.scala53
-rw-r--r--test/files/jvm/replyreactor.check1
-rw-r--r--test/files/jvm/replyreactor.scala43
-rw-r--r--test/files/jvm/scala-concurrent-tck.check1
-rw-r--r--test/files/jvm/scala-concurrent-tck.scala124
-rw-r--r--test/files/jvm/scheduler-adapter.check6
-rw-r--r--test/files/jvm/scheduler-adapter.scala54
-rw-r--r--test/files/jvm/t1449.check1
-rw-r--r--test/files/jvm/t1449.scala28
-rw-r--r--test/files/jvm/t1948.scala26
-rw-r--r--test/files/jvm/t2359.check5
-rw-r--r--test/files/jvm/t2359.scala48
-rw-r--r--test/files/jvm/t2530.check21
-rw-r--r--test/files/jvm/t2530.scala98
-rw-r--r--test/files/jvm/t3102.check2
-rw-r--r--test/files/jvm/t3102.scala39
-rw-r--r--test/files/jvm/t3356.check3
-rw-r--r--test/files/jvm/t3356.scala58
-rw-r--r--test/files/jvm/t3365.check5
-rw-r--r--test/files/jvm/t3365.scala68
-rw-r--r--test/files/jvm/t3407.check10
-rw-r--r--test/files/jvm/t3407.scala21
-rw-r--r--test/files/jvm/t3412-channel.check10
-rw-r--r--test/files/jvm/t3412-channel.scala40
-rw-r--r--test/files/jvm/t3412.check10
-rw-r--r--test/files/jvm/t3412.scala34
-rw-r--r--test/files/jvm/t3470.check3
-rw-r--r--test/files/jvm/t3470.scala32
-rw-r--r--test/files/jvm/t3838.check1
-rw-r--r--test/files/jvm/t3838.scala17
-rw-r--r--test/files/jvm/t7146.scala2
-rw-r--r--test/files/jvm/t8582.check3
-rw-r--r--test/files/jvm/t8582.flags1
-rw-r--r--test/files/jvm/try-type-tests.scala43
-rw-r--r--test/files/neg/beanInfoDeprecation.check6
-rw-r--r--test/files/neg/beanInfoDeprecation.flags1
-rw-r--r--test/files/neg/beanInfoDeprecation.scala2
-rw-r--r--test/files/neg/deprecated-target.check4
-rw-r--r--test/files/neg/deprecated-target.flags1
-rw-r--r--test/files/neg/deprecated-target.scala1
-rw-r--r--test/files/neg/logImplicits.check4
-rw-r--r--test/files/neg/names-defaults-neg.check48
-rw-r--r--test/files/neg/names-defaults-neg.scala4
-rw-r--r--test/files/neg/t6289.check6
-rw-r--r--test/files/neg/t8764.check6
-rw-r--r--test/files/neg/t8764.flags1
-rw-r--r--test/files/neg/t8764.scala9
-rw-r--r--test/files/neg/t8849.check7
-rw-r--r--test/files/neg/t8849.scala10
-rw-r--r--test/files/pos/MailBox.scala2
-rw-r--r--test/files/pos/alladin763.scala37
-rw-r--r--test/files/pos/functions.scala4
-rw-r--r--test/files/pos/t533.scala11
-rw-r--r--test/files/pos/t6778.scala5
-rw-r--r--test/files/pos/t7784.scala13
-rw-r--r--test/files/pos/t8462.scala11
-rw-r--r--test/files/pos/t8862a.scala47
-rw-r--r--test/files/pos/t8862b.scala12
-rw-r--r--test/files/pos/t9074.scala24
-rw-r--r--test/files/pos/t9074b.scala15
-rw-r--r--test/files/pos/t9131.scala12
-rw-r--r--test/files/pos/t9326a.scala6
-rw-r--r--test/files/run/analyzerPlugins.check8
-rw-r--r--test/files/run/classfile-format-51.scala1
-rw-r--r--test/files/run/classfile-format-52.scala1
-rw-r--r--test/files/run/concurrent-stream.check3
-rw-r--r--test/files/run/concurrent-stream.scala37
-rw-r--r--test/files/run/duration-coarsest.scala5
-rw-r--r--test/files/run/future-flatmap-exec-count.check1
-rw-r--r--test/files/run/inline-ex-handlers.check24
-rw-r--r--test/files/run/lub-visibility.check2
-rw-r--r--test/files/run/nothingTypeDce.flags2
-rw-r--r--test/files/run/nothingTypeDce.scala3
-rw-r--r--test/files/run/nothingTypeNoFramesNoDce.check1
-rw-r--r--test/files/run/nothingTypeNoFramesNoDce.flags1
-rw-r--r--test/files/run/nothingTypeNoFramesNoDce.scala61
-rw-r--r--test/files/run/nothingTypeNoOpt.flags2
-rw-r--r--test/files/run/repl-javap-app.check63
-rw-r--r--test/files/run/repl-javap-app.scala21
-rw-r--r--test/files/run/t2251b.check4
-rw-r--r--test/files/run/t4332.scala2
-rw-r--r--test/files/run/t6827.check12
-rw-r--r--test/files/run/t6827.scala20
-rw-r--r--test/files/run/t7521/Test.scala5
-rw-r--r--test/files/run/t7521/Wrapper.scala1
-rw-r--r--test/files/run/t7521b.check7
-rw-r--r--test/files/run/t7521b.scala20
-rw-r--r--test/files/run/t7775.scala43
-rw-r--r--test/files/run/t8575.scala32
-rw-r--r--test/files/run/t8575b.scala17
-rw-r--r--test/files/run/t8575c.scala23
-rw-r--r--test/files/run/t8710.scala17
-rw-r--r--test/files/run/t8764.check5
-rw-r--r--test/files/run/t8764.flags1
-rw-r--r--test/files/run/t8764.scala16
-rw-r--r--test/files/run/t8918-unary-ids.scala49
-rw-r--r--test/files/run/t8944/A_1.scala1
-rw-r--r--test/files/run/t8944/A_2.scala6
-rw-r--r--test/files/run/t8944/Test_1.scala3
-rw-r--r--test/files/run/t8944b.scala9
-rw-r--r--test/files/run/t8944c.check5
-rw-r--r--test/files/run/t8944c.scala8
-rw-r--r--test/files/run/t8955.scala12
-rw-r--r--test/files/run/t9174.check19
-rw-r--r--test/files/run/t9174.scala11
-rw-r--r--test/files/run/t9200/Test.java6
-rw-r--r--test/files/run/t9200/test.scala12
-rwxr-xr-xtest/files/scalacheck/concurrent-map.scala76
-rw-r--r--test/junit/scala/collection/IteratorTest.scala22
-rw-r--r--test/junit/scala/collection/SeqViewTest.scala16
-rw-r--r--test/junit/scala/collection/SetMapConsistencyTest.scala11
-rw-r--r--test/junit/scala/collection/convert/NullSafetyTest.scala279
-rw-r--r--test/junit/scala/collection/immutable/StreamTest.scala108
-rw-r--r--test/junit/scala/sys/process/t7350.scala298
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/CompactLocalVariablesTest.scala4
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOpts.scala2
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala16
-rw-r--r--test/junit/scala/tools/nsc/settings/ScalaVersionTest.scala44
-rw-r--r--test/long-running/jvm/memleak2_actor.scala39
-rw-r--r--test/pending/jvm/actor-executor4.check21
-rw-r--r--test/pending/jvm/actor-executor4.scala64
-rw-r--r--test/pending/jvm/actor-receive-sender.check2
-rw-r--r--test/pending/jvm/actor-receive-sender.scala51
-rw-r--r--test/pending/jvm/actorgc_leak.check1
-rw-r--r--test/pending/jvm/actorgc_leak.scala63
-rw-r--r--test/pending/jvm/reactWithinZero.check2
-rw-r--r--test/pending/jvm/reactWithinZero.scala18
-rw-r--r--test/pending/jvm/receiveWithinZero.check2
-rw-r--r--test/pending/jvm/receiveWithinZero.scala18
-rw-r--r--test/pending/jvm/t1801.check6
-rw-r--r--test/pending/jvm/t1801.scala31
-rw-r--r--test/pending/jvm/t2515.check10
-rw-r--r--test/pending/jvm/t2515.scala43
-rw-r--r--test/pending/jvm/terminateLinked.check1
-rw-r--r--test/pending/jvm/terminateLinked.scala24
-rw-r--r--test/pending/jvm/timeout.check1
-rw-r--r--test/pending/jvm/timeout.scala38
-rw-r--r--test/pending/run/t5698/client.scala9
-rw-r--r--test/pending/run/t5698/server.scala22
-rw-r--r--test/pending/run/t5698/testmsg.scala5
-rw-r--r--test/scaladoc/filters1
-rw-r--r--test/scaladoc/run/t7905.check1
-rw-r--r--test/scaladoc/run/t7905.scala36
-rw-r--r--test/scaladoc/scalacheck/HtmlFactoryTest.scala13
-rw-r--r--versions.properties13
422 files changed, 3761 insertions, 22278 deletions
diff --git a/bincompat-backward.whitelist.conf b/bincompat-backward.whitelist.conf
index a1706d103d..637bd586e0 100644
--- a/bincompat-backward.whitelist.conf
+++ b/bincompat-backward.whitelist.conf
@@ -186,6 +186,15 @@ filter {
matchName="scala.reflect.runtime.SynchronizedOps.newNestedScope"
problemName=MissingMethodProblem
},
+ // see github.com/scala/scala/pull/3925, SI-8627, SI-6440
+ {
+ matchName="scala.collection.TraversableLike.filterImpl"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.immutable.Stream.filteredTail"
+ problemName=MissingMethodProblem
+ },
// https://github.com/scala/scala/pull/3848 -- SI-8680
{
matchName="scala.collection.immutable.Stream.scala$collection$immutable$Stream$$loop$6"
diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf
index 8fadb65f39..552c0d85f5 100644
--- a/bincompat-forward.whitelist.conf
+++ b/bincompat-forward.whitelist.conf
@@ -272,6 +272,103 @@ filter {
matchName="scala.reflect.api.PredefTypeCreator"
problemName=MissingClassProblem
},
+ // see github.com/scala/scala/pull/3925, SI-8627, SI-6440
+ {
+ matchName="scala.collection.IterableViewLike#AbstractTransformed.filterImpl"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.AbstractTraversable.filterImpl"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.TraversableViewLike#AbstractTransformed.filterImpl"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.TraversableLike.filterImpl"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.SeqViewLike#AbstractTransformed.filterImpl"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.immutable.TreeSet.filterImpl"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.immutable.Stream.filteredTail"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.immutable.Stream.filterImpl"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.immutable.Stream.filterImpl"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.immutable.StringOps.filterImpl"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.immutable.TreeMap.filterImpl"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.concurrent.TrieMap.filterImpl"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofByte.filterImpl"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofLong.filterImpl"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofUnit.filterImpl"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofInt.filterImpl"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofChar.filterImpl"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofRef.filterImpl"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofDouble.filterImpl"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofFloat.filterImpl"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofBoolean.filterImpl"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofShort.filterImpl"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.TreeSet.filterImpl"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.io.AbstractFile.filterImpl"
+ problemName=MissingMethodProblem
+ },
// https://github.com/scala/scala/pull/3848 -- SI-8680
{
matchName="scala.collection.immutable.Stream.scala$collection$immutable$Stream$$loop$6"
diff --git a/build-ant-macros.xml b/build-ant-macros.xml
index ace86cac49..d0c9c4d310 100644
--- a/build-ant-macros.xml
+++ b/build-ant-macros.xml
@@ -105,7 +105,7 @@
<then>
<stopwatch name="@{project}.timer"/>
<mkdir dir="${@{project}-classes}"/>
- <javac debug="true" srcdir="${src.dir}/@{project}" destdir="${@{project}-classes}" classpath="${@{project}-classes}" includes="**/*.java" target="1.6" source="1.5" compiler="javac1.6">
+ <javac debug="true" srcdir="${src.dir}/@{project}" destdir="${@{project}-classes}" classpath="${@{project}-classes}" includes="**/*.java" target="1.8" source="1.8" compiler="javac1.8">
<compilerarg line="${javac.args} @{args}"/>
</javac>
<if>
@@ -126,13 +126,13 @@
<attribute name="stage"/>
<!-- current stage (locker, quick, strap) -->
<attribute name="project"/>
- <!-- project: library/reflect/compiler/actors -->
+ <!-- project: library/reflect/compiler -->
<attribute name="destproject" default="@{project}"/>
<!-- overrides the output directory; used when building multiple projects into the same directory-->
<attribute name="args" default=""/>
<attribute name="excludes" default=""/>
<sequential>
- <javac debug="true" srcdir="${src.dir}/@{project}" destdir="${build-@{stage}.dir}/classes/@{destproject}" includes="**/*.java" excludes="@{excludes}" target="1.6" source="1.5">
+ <javac debug="true" srcdir="${src.dir}/@{project}" destdir="${build-@{stage}.dir}/classes/@{destproject}" includes="**/*.java" excludes="@{excludes}" target="1.8" source="1.8">
<compilerarg line="${javac.args} @{args}"/>
<classpath refid="@{stage}.@{destproject}.build.path"/>
</javac>
@@ -193,7 +193,7 @@
<attribute name="stage"/>
<!-- current stage (locker, quick, strap) -->
<attribute name="project"/>
- <!-- project: library/reflect/compiler/actors -->
+ <!-- project: library/reflect/compiler -->
<attribute name="srcpath" default="NOT SET"/>
<!-- needed to compile the library -->
<attribute name="args" default=""/>
@@ -262,7 +262,7 @@
<attribute name="stage"/>
<!-- current stage (locker, quick, strap) -->
<attribute name="project"/>
- <!-- project: library/reflect/compiler/actors -->
+ <!-- project: library/reflect/compiler -->
<attribute name="srcpath" default="NOT SET"/>
<!-- needed to compile the library -->
<attribute name="args" default=""/>
@@ -474,9 +474,7 @@
<filter token="SCALA_COMPILER_INTERACTIVE_VERSION" value="${scala-compiler-interactive.version.number}"/>
<filter token="XML_VERSION" value="${scala-xml.version.number}" />
<filter token="PARSER_COMBINATORS_VERSION" value="${scala-parser-combinators.version.number}" />
- <filter token="CONTINUATIONS_PLUGIN_VERSION" value="${scala-continuations-plugin.version.number}" />
- <filter token="CONTINUATIONS_LIBRARY_VERSION" value="${scala-continuations-library.version.number}" />
- <filter token="SCALA_SWING_VERSION" value="${scala-swing.version.number}" />
+ <filter token="SCALA_SWING_VERSION" value="${scala-swing.version.number}" />
</filterset>
</copy>
<bnd classpath="${@{project}.jar}" eclipse="false" failok="false" exceptions="true" files="${build-osgi.dir}/${@{project}.name}.bnd" output="${build-osgi.dir}"/>
@@ -600,14 +598,10 @@
<filter token="SCALA_FULL_VERSION" value="${scala.full.version}" />
<filter token="XML_VERSION" value="${scala-xml.version.number}" />
<filter token="PARSER_COMBINATORS_VERSION" value="${scala-parser-combinators.version.number}" />
- <filter token="CONTINUATIONS_PLUGIN_VERSION" value="${scala-continuations-plugin.version.number}" />
- <filter token="CONTINUATIONS_LIBRARY_VERSION" value="${scala-continuations-library.version.number}" />
- <filter token="SCALA_SWING_VERSION" value="${scala-swing.version.number}" />
+ <filter token="SCALA_SWING_VERSION" value="${scala-swing.version.number}" />
<filter token="RELEASE_REPOSITORY" value="${remote.release.repository}" />
<filter token="SNAPSHOT_REPOSITORY" value="${remote.snapshot.repository}" />
<filter token="JLINE_VERSION" value="${jline.version}" />
- <filter token="AKKA_ACTOR_VERSION" value="${akka-actor.version.number}" />
- <filter token="ACTORS_MIGRATION_VERSION" value="${actors-migration.version.number}" />
<!-- TODO modularize compiler.
<filter token="SCALA_COMPILER_DOC_VERSION" value="${scala-compiler-doc.version.number}" />
@@ -746,7 +740,6 @@
<deploy-one name="scala-compiler-interactive" local="@{local}" signed="@{signed}"/>
-->
- <deploy-one name="scala-actors" local="@{local}" signed="@{signed}"/>
<deploy-one name="scalap" local="@{local}" signed="@{signed}"/>
</sequential>
</macrodef>
diff --git a/build.number b/build.number
index f5c5adfc0f..7c7e26fd09 100644
--- a/build.number
+++ b/build.number
@@ -3,8 +3,8 @@
# SNAPSHOT / nightly builds and local builds of source checkouts.
version.major=2
-version.minor=11
-version.patch=7
+version.minor=12
+version.patch=0
# This is the -N part of a version (2.9.1-1). If it's 0, it's dropped from maven versions. It should not be used again.
version.bnum=0
diff --git a/build.sbt b/build.sbt
index 1e3bef2541..03e0e73fc8 100644
--- a/build.sbt
+++ b/build.sbt
@@ -83,7 +83,7 @@ lazy val commonSettings = clearSourceAndResourceDirectories ++ Seq[Setting[_]](
// we always assume that Java classes are standalone and do not have any dependency
// on Scala classes
compileOrder := CompileOrder.JavaThenScala,
- javacOptions in Compile ++= Seq("-g", "-source", "1.5", "-target", "1.6"),
+ javacOptions in Compile ++= Seq("-g", "-source", "1.8", "-target", "1.8"),
// we don't want any unmanaged jars; as a reminder: unmanaged jar is a jar stored
// directly on the file system and it's not resolved through Ivy
// Ant's build stored unmanaged jars in `lib/` directory
@@ -212,13 +212,6 @@ lazy val scaladoc = configureAsSubproject(project)
lazy val scalap = configureAsSubproject(project).
dependsOn(compiler)
-// deprecated Scala Actors project
-// TODO: it packages into actors.jar but it should be scala-actors.jar
-lazy val actors = configureAsSubproject(project)
- .settings(generatePropertiesFileSettings: _*)
- .settings(name := "scala-actors")
- .dependsOn(library)
-
lazy val forkjoin = configureAsForkOfJavaProject(project)
lazy val partestExtras = configureAsSubproject(Project("partest-extras", file(".") / "src" / "partest-extras"))
@@ -259,7 +252,7 @@ lazy val partestJavaAgent = (project in file(".") / "src" / "partest-javaagent")
)
lazy val test = project.
- dependsOn(compiler, interactive, actors, repl, scalap, partestExtras, partestJavaAgent, scaladoc).
+ dependsOn(compiler, interactive, repl, scalap, partestExtras, partestJavaAgent, scaladoc).
configs(IntegrationTest).
settings(disableDocsAndPublishingTasks: _*).
settings(commonSettings: _*).
@@ -290,7 +283,7 @@ lazy val test = project.
lazy val root = (project in file(".")).
aggregate(library, forkjoin, reflect, compiler, interactive, repl,
- scaladoc, scalap, actors, partestExtras, junit).settings(
+ scaladoc, scalap, partestExtras, junit).settings(
sources in Compile := Seq.empty,
onLoadMessage := """|*** Welcome to the sbt build definition for Scala! ***
|This build definition has an EXPERIMENTAL status. If you are not
diff --git a/build.xml b/build.xml
index 589e1931b8..a52139219d 100755
--- a/build.xml
+++ b/build.xml
@@ -75,8 +75,8 @@ TODO:
<target name="nightly"><optimized name="all.done"/></target>
<target name="nightly.checkall"> <antcall target="all.done"> <param name="partest.scalac_opts" value="-Ycheck:all"/></antcall></target>
- <!-- The IDE build requires actors/swing/continuations, so need to publish them during PR validation until they are modules -->
- <target name="publish-opt-nodocs" description="Publishes Scala (optimized) without generating docs/testing (library/reflect/compiler/actors/swing/continuations).">
+ <!-- The IDE build requires swing, so need to publish them during PR validation until they are modules -->
+ <target name="publish-opt-nodocs" description="Publishes Scala (optimized) without generating docs/testing (library/reflect/compiler/swing).">
<antcall target="publish">
<param name="docs.skip" value="1"/>
<param name="scalac.args.optimise" value="-optimise"/>
@@ -193,7 +193,7 @@ TODO:
<!-- if ANT_OPTS is already set by the environment, it will be unaltered,
but if it is unset it will take this default value. -->
- <property name="env.ANT_OPTS" value="-Xms1536M -Xmx1536M -Xss1M -XX:MaxPermSize=192M -XX:+UseParallelGC" />
+ <property name="env.ANT_OPTS" value="-Xms1536M -Xmx1536M -Xss1M -XX:+UseParallelGC" />
<property name="scalacfork.jvmargs" value="${env.ANT_OPTS} ${jvm.opts}"/>
@@ -349,9 +349,6 @@ TODO:
necessary cross suffix (usually something like "_2.11.0-M6". -->
<prepareCross name="scala-xml" />
<prepareCross name="scala-parser-combinators" />
- <property name="scala-continuations-plugin.cross.suffix" value="_${scala.full.version}"/>
- <prepareCross name="scala-continuations-plugin" />
- <prepareCross name="scala-continuations-library"/>
<prepareCross name="scala-swing"/>
<prepareCross name="partest"/>
<prepareCross name="scalacheck"/>
@@ -390,8 +387,6 @@ TODO:
<artifact:remoteRepository refid="extra-repo"/>
<dependency groupId="org.scala-lang.modules" artifactId="scala-xml${scala-xml.cross}" version="${scala-xml.version.number}"/>
<dependency groupId="org.scala-lang.modules" artifactId="scala-parser-combinators${scala-parser-combinators.cross}" version="${scala-parser-combinators.version.number}"/>
- <dependency groupId="org.scala-lang.plugins" artifactId="scala-continuations-plugin${scala-continuations-plugin.cross}" version="${scala-continuations-plugin.version.number}"/>
- <dependency groupId="org.scala-lang.plugins" artifactId="scala-continuations-library${scala-continuations-library.cross}" version="${scala-continuations-library.version.number}"/>
<dependency groupId="org.scala-lang.modules" artifactId="scala-swing${scala-swing.cross}" version="${scala-swing.version.number}"/>
</artifact:dependencies>
@@ -410,8 +405,6 @@ TODO:
<propertyForCrossedArtifact name="scala-parser-combinators" jar="org.scala-lang.modules:scala-parser-combinators"/>
<propertyForCrossedArtifact name="scala-xml" jar="org.scala-lang.modules:scala-xml"/>
- <propertyForCrossedArtifact name="scala-continuations-plugin" jar="org.scala-lang.plugins:scala-continuations-plugin"/>
- <propertyForCrossedArtifact name="scala-continuations-library" jar="org.scala-lang.plugins:scala-continuations-library"/>
<propertyForCrossedArtifact name="scala-swing" jar="org.scala-lang.modules:scala-swing"/>
<!-- BND support -->
@@ -488,20 +481,12 @@ TODO:
<!-- some default in case something went wrong getting the revision -->
<property name="version.number" value="-unknown-"/>
- <condition property="has.java6">
- <equals arg1="${ant.java.version}" arg2="1.6"/>
- </condition>
- <condition property="has.java7">
- <equals arg1="${ant.java.version}" arg2="1.7"/>
- </condition>
<condition property="has.java8">
<equals arg1="${ant.java.version}" arg2="1.8"/>
</condition>
<condition property="has.unsupported.jdk">
<not><or>
<isset property="has.java8" />
- <isset property="has.java7" />
- <isset property="has.java6" />
</or></not>
</condition>
@@ -602,14 +587,9 @@ TODO:
<echo message="Updating `versions.properties`:"/>
<echo message="starr.version = ${starr.version}"/>
<echo message="scala.binary.version = ${scala.binary.version}"/>
- <echo message="scala.full.version = ${scala.full.version}"/>
<echo message="scala-xml.version.number = ${scala-xml.version.number}"/>
<echo message="scala-parser-combinators.version.number = ${scala-parser-combinators.version.number}"/>
- <echo message="scala-continuations-plugin.version.number = ${scala-continuations-plugin.version.number}"/>
- <echo message="scala-continuations-library.version.number = ${scala-continuations-library.version.number}"/>
<echo message="scala-swing.version.number = ${scala-swing.version.number}"/>
- <echo message="akka-actor.version.number = ${akka-actor.version.number}"/>
- <echo message="actors-migration.version.number = ${actors-migration.version.number}"/>
<echo message="jline.version = ${jline.version}"/>
<echo message="partest.version.number = ${partest.version.number}"/>
<echo message="scalacheck.version.number = ${scalacheck.version.number}"/>
@@ -617,14 +597,9 @@ TODO:
<propertyfile file="versions.properties">
<entry key="starr.version" value="${starr.version}"/>
<entry key="scala.binary.version" value="${scala.binary.version}"/>
- <entry key="scala.full.version" value="${scala.full.version}"/>
<entry key="scala-xml.version.number" value="${scala-xml.version.number}"/>
<entry key="scala-parser-combinators.version.number" value="${scala-parser-combinators.version.number}"/>
- <entry key="scala-continuations-plugin.version.number" value="${scala-continuations-plugin.version.number}"/>
- <entry key="scala-continuations-library.version.number" value="${scala-continuations-library.version.number}"/>
<entry key="scala-swing.version.number" value="${scala-swing.version.number}"/>
- <entry key="akka-actor.version.number" value="${akka-actor.version.number}"/>
- <entry key="actors-migration.version.number" value="${actors-migration.version.number}"/>
<entry key="jline.version" value="${jline.version}"/>
<entry key="partest.version.number" value="${partest.version.number}"/>
<entry key="scalacheck.version.number" value="${scalacheck.version.number}"/>
@@ -660,26 +635,12 @@ TODO:
<property name="scaladoc.version" value="${scala-compiler-doc.version.number}"/>
<property name="scaladoc.targetjar" value="scala-compiler-doc_${scala.binary.version}-${scala-compiler-doc.version.number}.jar"/>
- <property name="actors.description" value="Scala Actors Library"/>
-
<property name="swing.description" value="Scala Swing Library"/>
<property name="swing.package" value="modules."/>
<property name="swing.jar" value="${scala-swing}"/>
<property name="swing.src" value="false"/>
<property name="swing.srcjar" value="${scala-swing-sources}"/>
- <property name="continuations-plugin.description" value="Scala Delimited Continuations Compiler Plugin"/>
- <property name="continuations-plugin.package" value="plugins." />
- <property name="continuations-plugin.jar" value="${scala-continuations-plugin}"/>
- <property name="continuations-plugin.src" value="false"/>
- <property name="continuations-plugin.srcjar" value="${scala-continuations-plugin-sources}"/>
-
- <property name="continuations-library.description" value="Scala Delimited Continuations Library"/>
- <property name="continuations-library.package" value="plugins." />
- <property name="continuations-library.jar" value="${scala-continuations-library}"/>
- <property name="continuations-library.src" value="false"/>
- <property name="continuations-library.srcjar" value="${scala-continuations-library-sources}"/>
-
<property name="parser-combinators.description" value="Scala Parser Combinators Library"/>
<property name="parser-combinators.package" value="modules."/>
<property name="parser-combinators.jar" value="${scala-parser-combinators}"/>
@@ -700,7 +661,7 @@ TODO:
<property name="partest-javaagent.description" value="Scala Compiler Testing Tool (compiler-specific java agent)"/>
<!-- projects without project-specific options: forkjoin, manual, bin, repl -->
- <for list="actors,compiler,interactive,scaladoc,library,parser-combinators,partest,partest-extras,partest-javaagent,reflect,scalap,swing,xml,continuations-plugin,continuations-library,repl-jline" param="project">
+ <for list="compiler,interactive,scaladoc,library,parser-combinators,partest,partest-extras,partest-javaagent,reflect,scalap,swing,xml,repl-jline" param="project">
<sequential>
<!-- description is mandatory -->
<init-project-prop project="@{project}" name="package" default=""/> <!-- used by mvn-package, copy-bundle, make-bundle -->
@@ -749,7 +710,7 @@ TODO:
There must be a variable of the shape @{stage}.@{project}.build.path
for all @{stage} in locker, quick, strap
and all @{project} in library, reflect, compiler
- when stage is quick, @{project} also includes: actors, repl, scalap
+ when stage is quick, @{project} also includes: repl, scalap
NOTE: interactive, scaladoc, are only used upto quick; they are still packed into the compiler jar
-->
@@ -784,11 +745,6 @@ TODO:
<path refid="scala-java8-compat.libs"/>
</path>
- <path id="quick.actors.build.path">
- <path refid="quick.library.build.path"/>
- <pathelement location="${build-quick.dir}/classes/actors"/>
- </path>
-
<path id="quick.reflect.build.path">
<path refid="quick.library.build.path"/>
<pathelement location="${build-quick.dir}/classes/reflect"/>
@@ -818,7 +774,13 @@ TODO:
<path id="quick.partest-extras.build.path">
<path refid="asm.classpath"/>
- <path refid="partest.classpath"/>
+ <restrict>
+ <path refid="partest.classpath"/>
+ <rsel:not><rsel:or>
+ <rsel:name name="scala-library*.jar"/>
+ </rsel:or></rsel:not>
+ </restrict>
+
<path refid="quick.compiler.build.path"/>
<pathelement location="${build-quick.dir}/classes/repl"/>
<!-- for the java dependency: Profiler.java -->
@@ -843,7 +805,6 @@ TODO:
<path id="quick.bin.tool.path">
<path refid="quick.repl.build.path"/>
- <path refid="quick.actors.build.path"/>
<pathelement location="${build-quick.dir}/classes/scalap"/>
<pathelement location="${build-quick.dir}/classes/scaladoc"/>
<path refid="external-modules-nocore"/>
@@ -863,7 +824,6 @@ TODO:
<pathelement location="${library.jar}"/>
<pathelement location="${xml.jar}"/>
<pathelement location="${parser-combinators.jar}"/>
- <pathelement location="${actors.jar}"/>
<pathelement location="${reflect.jar}"/>
<pathelement location="${compiler.jar}"/>
<!-- TODO modularize compiler: <pathelement location="${scaladoc.jar}"/> -->
@@ -878,10 +838,6 @@ TODO:
<fileset refid="scala-java8-compat.fileset"/>
</path>
- <path id="pack.actors.files">
- <fileset dir="${build-quick.dir}/classes/actors"/>
- </path>
-
<path id="pack.repl-jline.files"> <fileset dir="${build-quick.dir}/classes/repl-jline"/> </path>
<path id="pack.compiler.files">
@@ -931,7 +887,6 @@ TODO:
<path id="docs.scaladoc.build.path"> <path refid="quick.scaladoc.build.path"/> </path>
<path id="docs.interactive.build.path"> <path refid="quick.interactive.build.path"/> </path>
<path id="docs.scalap.build.path"> <path refid="quick.scalap.build.path"/> </path>
- <path id="docs.actors.build.path"> <path refid="quick.actors.build.path"/> </path>
<!-- run-time classpath for scaladoc TODO: resolve through maven -->
<path id="scaladoc.classpath">
@@ -987,9 +942,8 @@ TODO:
<pathelement location="${interactive.jar}"/>
-->
- <!-- TODO: move scalap & actors out of repo -->
+ <!-- TODO: move scalap out of repo -->
<pathelement location="${scalap.jar}"/>
- <pathelement location="${actors.jar}"/>
<!-- partest's dependencies, which marks most of its dependencies as provided,
(but not scala-library, so we filter that one out...)
@@ -1012,7 +966,6 @@ TODO:
<rsel:name name="scala-library*.jar"/>
<rsel:name name="scala-compiler*.jar"/>
<rsel:name name="scala-reflect*.jar"/>
- <rsel:name name="scala-actors*.jar"/>
<rsel:name name="scala-parser-combinators*.jar"/>
<rsel:name name="scala-xml*.jar"/>
</rsel:or></rsel:not>
@@ -1040,7 +993,6 @@ TODO:
<pathelement location="${build-osgi.dir}/org.scala-lang.scala-library.jar"/>
<pathelement location="${build-osgi.dir}/org.scala-lang.scala-reflect.jar"/>
<pathelement location="${build-osgi.dir}/org.scala-lang.scala-compiler.jar"/>
- <pathelement location="${build-osgi.dir}/org.scala-lang.scala-actors.jar"/>
<path refid="pax.exam.classpath"/>
<path refid="forkjoin.classpath"/>
</path>
@@ -1204,9 +1156,6 @@ TODO:
<target name="quick.scalap" depends="quick.repl">
<staged-build with="locker" stage="quick" project="scalap"/> </target>
- <target name="quick.actors" depends="quick.lib">
- <staged-build with="locker" stage="quick" project="actors"/> </target>
-
<target name="quick.modules" depends="quick.repl, quick.scaladoc, quick.interactive, quick.scalap"/>
@@ -1258,14 +1207,12 @@ TODO:
<target name="pack.interactive" depends="quick.interactive"> <staged-pack project="interactive"/> </target>
-->
- <target name="pack.actors" depends="quick.actors"> <staged-pack project="actors"/> </target>
-
<target name="pack.scalap" depends="quick.scalap"> <staged-pack project="scalap"/> </target>
<target name="pack.core" depends="pack.reflect, pack.comp, pack.lib"/>
<!-- TODO modularize compiler: pack.scaladoc, pack.interactive, -->
- <target name="pack.modules" depends="pack.actors, pack.scalap">
+ <target name="pack.modules" depends="pack.scalap">
<copy todir="${build-pack.dir}/lib">
<path refid="external-modules-nocore" />
<mapper type="flatten" />
@@ -1371,10 +1318,6 @@ TODO:
<include name="${scaladoc.jar}"/>
-->
- <file name="${actors.jar}"/>
-
- <file name="${continuations-plugin.jar}"/>
- <file name="${continuations-library.jar}"/>
<file name="${parser-combinators.jar}"/>
<file name="${xml.jar}"/>
<file name="${swing.jar}"/>
@@ -1399,13 +1342,6 @@ TODO:
</make-bundle>
-->
- <make-bundle project="actors">
- <fileset dir="${src.dir}/actors"/>
- </make-bundle>
-
-
- <make-bundle project="continuations-plugin"/>
- <make-bundle project="continuations-library"/>
<make-bundle project="parser-combinators"/>
<make-bundle project="xml"/>
<make-bundle project="swing"/>
@@ -1552,6 +1488,10 @@ TODO:
<mkdir dir="${test.junit.classes}"/>
<echo message="Note: details of failed tests will be output to ${build-junit.dir}"/>
+ <propertyfile file = "${test.junit.classes}/classpath.properties">
+ <entry key = "test.junit.compiler.build.path" value="${toString:test.junit.compiler.build.path}"/>
+ </propertyfile>
+
<if><isset property="test.method" /><then><property name="test.methods" value="${test.method}" /></then></if>
<junit fork="yes" haltonfailure="yes" printsummary="on">
<classpath refid="test.junit.compiler.build.path"/>
@@ -1647,8 +1587,9 @@ TODO:
<target name="test.bc-opt" description="Optimized version of test.bc."> <optimized name="test.bc"/></target>
<target name="test.bc" depends="bc.prepare, pack.lib, pack.reflect" unless="test.bc.skip">
- <bc.check project="library"/>
- <bc.check project="reflect"/>
+ <echo message="binary compatibility testing disabled in the 2.12.x branch"/>
+ <!-- <bc.check project="library"/> -->
+ <!-- <bc.check project="reflect"/> -->
</target>
<!-- ===========================================================================
@@ -1715,12 +1656,6 @@ TODO:
</target>
-->
- <target name="docs.actors" depends="docs.start" unless="docs.skip">
- <staged-docs project="actors">
- <include name="**/*.scala"/>
- </staged-docs>
- </target>
-
<target name="docs.scalap" depends="docs.start" unless="docs.skip">
<staged-docs project="scalap">
<include name="**/*.scala"/>
@@ -1729,7 +1664,7 @@ TODO:
<target name="docs.core" depends="docs.lib, docs.reflect, docs.comp" unless="docs.skip"/>
<!-- TODO modularize compiler: docs.scaladoc, docs.interactive, -->
- <target name="docs.done" depends="docs.core, docs.actors, docs.scalap" unless="docs.skip"/>
+ <target name="docs.done" depends="docs.core, docs.scalap" unless="docs.skip"/>
<!-- doc/ and man/ -->
<target name="pack.doc" depends="scaladoc.task" unless="docs.skip"> <!-- depends on scaladoc.task for scalac taskdef -->
@@ -1804,8 +1739,6 @@ MAIN DISTRIBUTION PACKAGING
<mvn-package project="scaladoc"/>
-->
- <mvn-package project="actors"/>
-
<!-- don't bother fitting scalap into the mould: it will move out soon -->
<copy tofile="${dist.maven}/scalap/scalap-pom.xml" file="${src.dir}/build/maven/scalap-pom.xml" overwrite="true"/>
<copy tofile="${dist.maven}/scalap/scalap.jar" file="${scalap.jar}" overwrite="true"/>
diff --git a/dbuild-meta.json b/dbuild-meta.json
index 90d0104ec1..4806f9fa5a 100644
--- a/dbuild-meta.json
+++ b/dbuild-meta.json
@@ -1,100 +1,82 @@
{
- "version": "2.11.0",
- "subproj": [],
- "projects": [
+ "projects" : [
{
- "artifacts": [
+ "artifacts" : [
{
- "extension": "jar",
- "name": "scala-library",
- "organization": "org.scala-lang"
+ "extension" : "jar",
+ "name" : "scala-library",
+ "organization" : "org.scala-lang"
}
],
- "dependencies": [],
- "name": "scala-library",
- "organization": "org.scala-lang"
+ "dependencies" : [],
+ "name" : "scala-library",
+ "organization" : "org.scala-lang"
},
{
- "artifacts": [
+ "artifacts" : [
{
- "extension": "jar",
- "name": "scala-reflect",
- "organization": "org.scala-lang"
+ "extension" : "jar",
+ "name" : "scala-reflect",
+ "organization" : "org.scala-lang"
}
],
- "dependencies": [
+ "dependencies" : [
{
- "extension": "jar",
- "name": "scala-library",
- "organization": "org.scala-lang"
+ "extension" : "jar",
+ "name" : "scala-library",
+ "organization" : "org.scala-lang"
}
],
- "name": "scala-reflect",
- "organization": "org.scala-lang"
+ "name" : "scala-reflect",
+ "organization" : "org.scala-lang"
},
{
- "artifacts": [
+ "artifacts" : [
{
- "extension": "jar",
- "name": "scala-compiler",
- "organization": "org.scala-lang"
+ "extension" : "jar",
+ "name" : "scala-compiler",
+ "organization" : "org.scala-lang"
}
],
- "dependencies": [
+ "dependencies" : [
{
- "extension": "jar",
- "name": "scala-reflect",
- "organization": "org.scala-lang"
+ "extension" : "jar",
+ "name" : "scala-reflect",
+ "organization" : "org.scala-lang"
},
{
- "extension": "jar",
- "name": "scala-xml",
- "organization": "org.scala-lang.modules"
+ "extension" : "jar",
+ "name" : "scala-xml",
+ "organization" : "org.scala-lang.modules"
},
{
- "extension": "jar",
- "name": "scala-parser-combinators",
- "organization": "org.scala-lang.modules"
+ "extension" : "jar",
+ "name" : "scala-parser-combinators",
+ "organization" : "org.scala-lang.modules"
}
],
- "name": "scala-compiler",
- "organization": "org.scala-lang"
+ "name" : "scala-compiler",
+ "organization" : "org.scala-lang"
},
{
- "artifacts": [
+ "artifacts" : [
{
- "extension": "jar",
- "name": "scala-actors",
- "organization": "org.scala-lang"
+ "extension" : "jar",
+ "name" : "scalap",
+ "organization" : "org.scala-lang"
}
],
- "dependencies": [
+ "dependencies" : [
{
- "extension": "jar",
- "name": "scala-library",
- "organization": "org.scala-lang"
+ "extension" : "jar",
+ "name" : "scala-compiler",
+ "organization" : "org.scala-lang"
}
],
- "name": "scala-actors",
- "organization": "org.scala-lang"
- },
- {
- "artifacts": [
- {
- "extension": "jar",
- "name": "scalap",
- "organization": "org.scala-lang"
- }
- ],
- "dependencies": [
- {
- "extension": "jar",
- "name": "scala-compiler",
- "organization": "org.scala-lang"
- }
- ],
- "name": "scalap",
- "organization": "org.scala-lang"
+ "name" : "scalap",
+ "organization" : "org.scala-lang"
}
- ]
+ ],
+ "subproj" : [],
+ "version" : "2.12.0"
}
diff --git a/scripts/jobs/integrate/bootstrap b/scripts/jobs/integrate/bootstrap
index 5048f3fdb9..ccc62c0d45 100755
--- a/scripts/jobs/integrate/bootstrap
+++ b/scripts/jobs/integrate/bootstrap
@@ -187,7 +187,7 @@ sbtBuild() {
sbtResolve() {
cd $baseDir/resolutionScratch_
touch build.sbt
- # Can be set to `full` if a module requires cross-versioning against the full Scala version, like the continuations plugin.
+ # Can be set to `full` if a module requires cross-versioning against the full Scala version, like the continuations plugin used to.
cross=${4-binary}
echo "### sbtResolve: $sbtCmd $sbtArgs " "${scalaVersionTasks[@]}" "\"$1\" % \"$2\" % \"$3\" cross CrossVersion.$cross"
$sbtCmd $sbtArgs "${scalaVersionTasks[@]}" \
@@ -251,27 +251,6 @@ buildPartest() {
# fi
# }
-buildContinuations() {
- if [ "$CONT_PLUG_BUILT" != "yes" ] && [ "$forceRebuild" != "yes" ] && ( sbtResolve "org.scala-lang.plugins" "scala-continuations-plugin" $CONTINUATIONS_VER full )
- then echo "Found scala-continuations-plugin $CONTINUATIONS_VER; not building."
- else
- update scala scala-continuations $CONTINUATIONS_REF && gfxd
-
- $sbtCmd $sbtArgs 'project plugin' "${scalaVersionTasks[@]}" "${publishTasks[@]}" \
- 'set version := "'$CONTINUATIONS_VER'"' $clean "compile:package" test "${buildTasks[@]}" # https://github.com/scala/scala-continuations/pull/4
- CONT_PLUG_BUILT="yes"
- fi
-
- if [ "$CONT_LIB_BUILT" != "yes" ] && [ "$forceRebuild" != "yes" ] && ( sbtResolve "org.scala-lang.plugins" "scala-continuations-library" $CONTINUATIONS_VER )
- then echo "Found scala-continuations-library $CONTINUATIONS_VER; not building."
- else
- update scala scala-continuations $CONTINUATIONS_REF && gfxd
- $sbtCmd $sbtArgs 'project library' "${scalaVersionTasks[@]}" "${publishTasks[@]}" \
- 'set version := "'$CONTINUATIONS_VER'"' $clean test "${buildTasks[@]}"
- CONT_LIB_BUILT="yes"
- fi
-}
-
buildSwing() {
if [ "$SWING_BUILT" != "yes" ] && [ "$forceRebuild" != "yes" ] && ( sbtResolve "org.scala-lang.modules" "scala-swing" $SWING_VER )
then echo "Found scala-swing $SWING_VER; not building."
@@ -282,18 +261,6 @@ buildSwing() {
fi
}
-buildActorsMigration(){
- if [ "$ACTORS_MIGRATION_BUILT" != "yes" ] && [ "$forceRebuild" != "yes" ] && ( sbtResolve "org.scala-lang" "scala-actors-migration" $ACTORS_MIGRATION_VER )
- then echo "Found scala-actors-migration $ACTORS_MIGRATION_VER; not building."
- else
- update scala actors-migration "$ACTORS_MIGRATION_REF" && gfxd
- # not running tests because
- # [error] Test scala.actors.migration.NestedReact.testNestedReactAkka failed: java.util.concurrent.TimeoutException: Futures timed out after [20 seconds]
- sbtBuild 'set version := "'$ACTORS_MIGRATION_VER'"' 'set VersionKeys.continuationsVersion := "'$CONTINUATIONS_VER'"' $clean "${buildTasks[@]}"
- ACTORS_MIGRATION_BUILT="yes"
- fi
-}
-
# should only be called with publishTasks publishing to private-repo
buildScalacheck(){
if [ "$SCALACHECK_BUILT" != "yes" ] && [ "$forceRebuild" != "yes" ] && ( sbtResolve "org.scalacheck" "scalacheck" $SCALACHECK_VER )
@@ -311,9 +278,7 @@ buildModules() {
buildTasks=($publishPrivateTask)
buildXML
buildParsers
- buildContinuations
buildSwing
- buildActorsMigration
buildScalacheck
buildPartest
# buildPartestIface
@@ -324,9 +289,7 @@ buildPublishedModules() {
buildTasks=($publishSonatypeTaskModules)
buildXML
buildParsers
- buildContinuations
buildSwing
- buildActorsMigration
buildPartest
# buildPartestIface
}
@@ -367,7 +330,7 @@ scalaVerToBinary() {
determineScalaVersion() {
cd $WORKSPACE
parseScalaProperties "versions.properties"
- echo "repo_ref=2.11.x" >> $baseDir/jenkins.properties # for the -dist downstream jobs that build the actual archives
+ echo "repo_ref=2.12.x" >> $baseDir/jenkins.properties # for the -dist downstream jobs that build the actual archives
# each of the branches below defines the following vars: SCALA_VER_BASE, SCALA_VER_SUFFIX, SCALADOC_SOURCE_LINKS_VER, publishToSonatype
@@ -433,17 +396,13 @@ deriveModuleVersions() {
# use versions.properties as defaults when no version specified on the command line
XML_VER=${XML_VER-$scala_xml_version_number}
PARSERS_VER=${PARSERS_VER-$scala_parser_combinators_version_number}
- CONTINUATIONS_VER=${CONTINUATIONS_VER-$scala_continuations_plugin_version_number}
SWING_VER=${SWING_VER-$scala_swing_version_number}
- ACTORS_MIGRATION_VER=${ACTORS_MIGRATION_VER-$actors_migration_version_number}
PARTEST_VER=${PARTEST_VER-$partest_version_number}
SCALACHECK_VER=${SCALACHECK_VER-$scalacheck_version_number}
XML_REF="v$XML_VER"
PARSERS_REF="v$PARSERS_VER"
- CONTINUATIONS_REF="v$CONTINUATIONS_VER"
SWING_REF="v$SWING_VER"
- ACTORS_MIGRATION_REF="v$ACTORS_MIGRATION_VER"
PARTEST_REF="v$PARTEST_VER"
# PARTEST_IFACE_REF="v$PARTEST_IFACE_VER"
SCALACHECK_REF="$SCALACHECK_VER" # no `v` in their tags
@@ -451,25 +410,19 @@ deriveModuleVersions() {
# use HEAD as default when no revision is specified on the command line
XML_REF=${XML_REF-"HEAD"}
PARSERS_REF=${PARSERS_REF-"HEAD"}
- CONTINUATIONS_REF=${CONTINUATIONS_REF-"HEAD"}
SWING_REF=${SWING_REF-"HEAD"}
- ACTORS_MIGRATION_REF=${ACTORS_MIGRATION_REF-"HEAD"}
PARTEST_REF=${PARTEST_REF-"HEAD"}
# PARTEST_IFACE_REF=${PARTEST_IFACE_REF-"HEAD"}
SCALACHECK_REF=${SCALACHECK_REF-"HEAD"}
XML_VER=$(deriveVersion scala scala-xml "$XML_REF")
PARSERS_VER=$(deriveVersion scala scala-parser-combinators "$PARSERS_REF")
- CONTINUATIONS_VER=$(deriveVersion scala scala-continuations "$CONTINUATIONS_REF")
SWING_VER=$(deriveVersion scala scala-swing "$SWING_REF")
- ACTORS_MIGRATION_VER=$(deriveVersion scala actors-migration "$ACTORS_MIGRATION_REF")
PARTEST_VER=$(deriveVersion scala scala-partest "$PARTEST_REF")
SCALACHECK_VER=$(deriveVersionAnyTag rickynils scalacheck "$SCALACHECK_REF")
fi
echo "Module versions (versioning strategy: $moduleVersioning):"
- echo "ACTORS_MIGRATION = $ACTORS_MIGRATION_VER at $ACTORS_MIGRATION_REF"
- echo "CONTINUATIONS = $CONTINUATIONS_VER at $CONTINUATIONS_REF"
echo "PARSERS = $PARSERS_VER at $PARSERS_REF"
echo "PARTEST = $PARTEST_VER at $PARTEST_REF"
echo "SCALACHECK = $SCALACHECK_VER at $SCALACHECK_REF"
@@ -508,9 +461,6 @@ constructUpdatedModuleVersions() {
# force the new module versions for building the core. these may be different from the values in versions.properties,
# either because the variables (XML_VER) were provided, or because we're building the modules from HEAD.
# in the common case, the values are the same as in versions.properties.
- updatedModuleVersions=("${updatedModuleVersions[@]}" "-Dactors-migration.version.number=$ACTORS_MIGRATION_VER")
- updatedModuleVersions=("${updatedModuleVersions[@]}" "-Dscala-continuations-library.version.number=$CONTINUATIONS_VER")
- updatedModuleVersions=("${updatedModuleVersions[@]}" "-Dscala-continuations-plugin.version.number=$CONTINUATIONS_VER")
updatedModuleVersions=("${updatedModuleVersions[@]}" "-Dscala-parser-combinators.version.number=$PARSERS_VER")
updatedModuleVersions=("${updatedModuleVersions[@]}" "-Dscala-swing.version.number=$SWING_VER")
updatedModuleVersions=("${updatedModuleVersions[@]}" "-Dscala-xml.version.number=$XML_VER")
@@ -518,8 +468,7 @@ constructUpdatedModuleVersions() {
updatedModuleVersions=("${updatedModuleVersions[@]}" "-Dpartest.version.number=$PARTEST_VER")
updatedModuleVersions=("${updatedModuleVersions[@]}" "-Dscalacheck.version.number=$SCALACHECK_VER")
- # allow overriding the akka-actors and jline version using a jenkins build parameter
- if [ ! -z "$AKKA_ACTOR_VER" ]; then updatedModuleVersions=("${updatedModuleVersions[@]}" "-Dakka-actor.version.number=$AKKA_ACTOR_VER"); fi
+ # allow overriding the jline version using a jenkins build parameter
if [ ! -z "$JLINE_VER" ] ; then updatedModuleVersions=("${updatedModuleVersions[@]}" "-Djline.version=$JLINE_VER"); fi
if [ ! -z "$SCALA_BINARY_VER" ]; then updatedModuleVersions=("${updatedModuleVersions[@]}" "-Dscala.binary.version=$SCALA_BINARY_VER"); fi
@@ -575,10 +524,7 @@ bootstrap() {
cd $baseDir
rm -rf build/ # must leave everything else in $baseDir for downstream jobs
- # scala.full.version determines the dependency of scala-dist on the continuations plugin,
- # which is fully cross-versioned (for $SCALA_VER, the version we're releasing)
ant -Dstarr.version=$SCALA_VER\
- -Dscala.full.version=$SCALA_VER\
-Dextra.repo.url=$releaseTempRepoUrl\
-Dmaven.version.suffix=$SCALA_VER_SUFFIX\
${updatedModuleVersions[@]} \
diff --git a/scripts/jobs/integrate/ide b/scripts/jobs/integrate/ide
index 1651ad2892..c39facbc3d 100755
--- a/scripts/jobs/integrate/ide
+++ b/scripts/jobs/integrate/ide
@@ -3,6 +3,9 @@
# requires env: scalaVersion (specifies binary already built from above checkout), WORKSPACE (provided by jenkins), repo_ref (HEAD of the scala checkout),
# requires files: $baseDir/versions.properties (from checkout -- defines version numbers for modules used to build scala for dbuild...)
+echo "IDE integration not yet available on 2.12.x. Punting."
+exit 0
+
# TODO: remove when integration is up and running
if [ "woele$_scabot_last" != "woele1" ]; then echo "Scabot didn't mark this as last commit -- skipping."; exit 0; fi
diff --git a/src/actors/scala/actors/AbstractActor.scala b/src/actors/scala/actors/AbstractActor.scala
deleted file mode 100644
index 28fe689e91..0000000000
--- a/src/actors/scala/actors/AbstractActor.scala
+++ /dev/null
@@ -1,30 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala.actors
-
-import scala.language.higherKinds
-
-/**
- * @author Philipp Haller
- *
- * @define actor actor
- */
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-trait AbstractActor extends OutputChannel[Any] with CanReply[Any, Any] {
-
- type Future[+R] <: scala.actors.Future[R]
-
- private[actors] def exiting: Boolean = false
-
- private[actors] def linkTo(to: AbstractActor): Unit
-
- private[actors] def unlinkFrom(from: AbstractActor): Unit
-
- private[actors] def exit(from: AbstractActor, reason: AnyRef): Unit
-}
diff --git a/src/actors/scala/actors/Actor.scala b/src/actors/scala/actors/Actor.scala
deleted file mode 100644
index 293335f720..0000000000
--- a/src/actors/scala/actors/Actor.scala
+++ /dev/null
@@ -1,411 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala.actors
-
-import scala.util.control.ControlThrowable
-import java.util.{Timer, TimerTask}
-import scala.language.implicitConversions
-
-/**
- * Provides functions for the definition of actors, as well as actor
- * operations, such as `receive`, `react`, `reply`, etc.
- *
- * @author Philipp Haller
- */
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-object Actor extends Combinators {
-
- /** State of an actor.
- *
- * - '''New''' -
- * Not yet started
- * - '''Runnable''' -
- * Executing
- * - '''Suspended''' -
- * Suspended, waiting in a `react`
- * - '''TimedSuspended''' -
- * Suspended, waiting in a `reactWithin`
- * - '''Blocked''' -
- * Blocked waiting in a `receive`
- * - '''TimedBlocked''' -
- * Blocked waiting in a `receiveWithin`
- * - '''Terminated''' -
- * Actor has terminated
- */
- object State extends Enumeration {
- val New,
- Runnable,
- Suspended,
- TimedSuspended,
- Blocked,
- TimedBlocked,
- Terminated = Value
- }
-
- private[actors] val tl = new ThreadLocal[InternalReplyReactor]
-
- // timer thread runs as daemon
- private[actors] val timer = new Timer(true)
-
- private[actors] val suspendException = new SuspendActorControl
-
- /**
- * Returns the currently executing actor. Should be used instead
- * of `'''this'''` in all blocks of code executed by actors.
- *
- * @return returns the currently executing actor.
- */
- def self: Actor = self(Scheduler).asInstanceOf[Actor]
-
- private[actors] def self(sched: IScheduler): InternalActor =
- rawSelf(sched).asInstanceOf[InternalActor]
-
- private[actors] def rawSelf: InternalReplyReactor =
- rawSelf(Scheduler)
-
- private[actors] def rawSelf(sched: IScheduler): InternalReplyReactor = {
- val s = tl.get
- if (s eq null) {
- val r = new ActorProxy(Thread.currentThread, sched)
- tl.set(r)
- r
- } else
- s
- }
-
- private def parentScheduler: IScheduler = {
- val s = tl.get
- if (s eq null) Scheduler else s.scheduler
- }
-
- /**
- * Resets an actor proxy associated with the current thread.
- * It replaces the implicit `ActorProxy` instance
- * of the current thread (if any) with a new instance.
- *
- * This permits to re-use the current thread as an actor
- * even if its `ActorProxy` has died for some reason.
- */
- def resetProxy() {
- val a = tl.get
- if ((null ne a) && a.isInstanceOf[ActorProxy])
- tl.set(new ActorProxy(Thread.currentThread, parentScheduler))
- }
-
- /**
- * Removes any reference to an `Actor` instance
- * currently stored in thread-local storage.
- *
- * This allows to release references from threads that are potentially
- * long-running or being re-used (e.g. inside a thread pool). Permanent
- * references in thread-local storage are a potential memory leak.
- */
- def clearSelf() {
- tl set null
- }
-
- /**
- * Factory method for creating and starting an actor.
- *
- * @example {{{
- * import scala.actors.Actor._
- * ...
- * val a = actor {
- * ...
- * }
- * }}}
- *
- * @param body the code block to be executed by the newly created actor
- * @return the newly created actor. Note that it is automatically started.
- */
- def actor(body: => Unit): Actor = {
- val a = new Actor {
- def act() = body
- override final val scheduler: IScheduler = parentScheduler
- }
- a.start()
- a
- }
-
- /**
- * Factory method for creating actors whose
- * body is defined using a `Responder`.
- *
- * @example {{{
- * import scala.actors.Actor._
- * import Responder.exec
- * ...
- * val a = reactor {
- * for {
- * res <- b !! MyRequest;
- * if exec(println("result: "+res))
- * } yield {}
- * }
- * }}}
- *
- * @param body the `Responder` to be executed by the newly created actor
- * @return the newly created actor. Note that it is automatically started.
- */
- def reactor(body: => Responder[Unit]): Actor = {
- val a = new Actor {
- def act() {
- Responder.run(body)
- }
- override final val scheduler: IScheduler = parentScheduler
- }
- a.start()
- a
- }
-
- /**
- * Receives the next message from the mailbox of the current actor `self`.
- */
- def ? : Any = self.?
-
- /**
- * Receives a message from the mailbox of `self`. Blocks if no message
- * matching any of the cases of `f` can be received.
- *
- * @example {{{
- * receive {
- * case "exit" => println("exiting")
- * case 42 => println("got the answer")
- * case x:Int => println("got an answer")
- * }
- * }}}
- *
- * @param f a partial function specifying patterns and actions
- * @return the result of processing the received message
- */
- def receive[A](f: PartialFunction[Any, A]): A =
- self.receive(f)
-
- /**
- * Receives a message from the mailbox of `self`. Blocks at most `msec`
- * milliseconds if no message matching any of the cases of `f` can be
- * received. If no message could be received the `TIMEOUT` action is
- * executed if specified.
- *
- * @param msec the time span before timeout
- * @param f a partial function specifying patterns and actions
- * @return the result of processing the received message
- */
- def receiveWithin[R](msec: Long)(f: PartialFunction[Any, R]): R =
- self.receiveWithin(msec)(f)
-
- /**
- * Lightweight variant of `receive`.
- *
- * Actions in `f` have to contain the rest of the computation of `self`,
- * as this method will never return.
- *
- * A common method of continuing the computation is to send a message
- * to another actor:
- * {{{
- * react {
- * case Get(from) =>
- * react {
- * case Put(x) => from ! x
- * }
- * }
- * }}}
- *
- * Another common method is to use `loop` to continuously `react` to messages:
- * {{{
- * loop {
- * react {
- * case Msg(data) => // process data
- * }
- * }
- * }}}
- *
- * @param f a partial function specifying patterns and actions
- * @return this function never returns
- */
- def react(f: PartialFunction[Any, Unit]): Nothing =
- rawSelf.react(f)
-
- /**
- * Lightweight variant of `receiveWithin`.
- *
- * Actions in `f` have to contain the rest of the computation of `self`,
- * as this method will never return.
- *
- * @param msec the time span before timeout
- * @param f a partial function specifying patterns and actions
- * @return this function never returns
- */
- def reactWithin(msec: Long)(f: PartialFunction[Any, Unit]): Nothing =
- self.reactWithin(msec)(f)
-
- def eventloop(f: PartialFunction[Any, Unit]): Nothing =
- rawSelf.react(new RecursiveProxyHandler(rawSelf, f))
-
- private class RecursiveProxyHandler(a: InternalReplyReactor, f: PartialFunction[Any, Unit])
- extends PartialFunction[Any, Unit] {
- def isDefinedAt(m: Any): Boolean =
- true // events are immediately removed from the mailbox
- def apply(m: Any) {
- if (f.isDefinedAt(m)) f(m)
- a.react(this)
- }
- }
-
- /**
- * Returns the actor which sent the last received message.
- */
- def sender: OutputChannel[Any] =
- rawSelf.internalSender
-
- /**
- * Sends `msg` to the actor waiting in a call to `!?`.
- */
- def reply(msg: Any): Unit =
- rawSelf.reply(msg)
-
- /**
- * Sends `()` to the actor waiting in a call to `!?`.
- */
- def reply(): Unit =
- rawSelf.reply(())
-
- /**
- * Returns the number of messages in `self`'s mailbox
- *
- * @return the number of messages in `self`'s mailbox
- */
- def mailboxSize: Int = rawSelf.mailboxSize
-
- /**
- * Converts a synchronous event-based operation into
- * an asynchronous `Responder`.
- *
- * @example {{{
- * val adder = reactor {
- * for {
- * _ <- respondOn(react) { case Add(a, b) => reply(a+b) }
- * } yield {}
- * }
- * }}}
- */
- def respondOn[A, B](fun: PartialFunction[A, Unit] => Nothing):
- PartialFunction[A, B] => Responder[B] =
- (caseBlock: PartialFunction[A, B]) => new Responder[B] {
- def respond(k: B => Unit) = fun(caseBlock andThen k)
- }
-
- private[actors] trait Body[a] {
- def andThen[b](other: => b): Unit
- }
-
- implicit def mkBody[a](body: => a) = new InternalActor.Body[a] {
- def andThen[b](other: => b): Unit = rawSelf.seq(body, other)
- }
-
- /**
- * Links `self` to actor `to`.
- *
- * @param to the actor to link to
- * @return the parameter actor
- */
- def link(to: AbstractActor): AbstractActor = self.link(to)
-
- /**
- * Links `self` to the actor defined by `body`.
- *
- * @param body the body of the actor to link to
- * @return the parameter actor
- */
- def link(body: => Unit): Actor = self.link(body)
-
- /**
- * Unlinks `self` from actor `from`.
- *
- * @param from the actor to unlink from
- */
- def unlink(from: AbstractActor): Unit = self.unlink(from)
-
- /**
- * Terminates execution of `self` with the following effect on
- * linked actors:
- *
- * For each linked actor `a` with `trapExit` set to `'''true'''`,
- * send message `Exit(self, reason)` to `a`.
- *
- * For each linked actor `a` with `trapExit` set to `'''false'''`
- * (default), call `a.exit(reason)` if `reason != 'normal`.
- */
- def exit(reason: AnyRef): Nothing = self.exit(reason)
-
- /**
- * Terminates execution of `self` with the following effect on
- * linked actors:
- *
- * For each linked actor `a` with `trapExit` set to `'''true'''`,
- * send message `Exit(self, 'normal)` to `a`.
- */
- def exit(): Nothing = rawSelf.exit()
-
-}
-
-/** Provides lightweight, concurrent actors. Actors are created by extending
- * the `Actor` trait (alternatively, one of the factory methods in its
- * companion object can be used). The behavior of an `Actor` subclass is
- * defined by implementing its `act` method:
- * {{{
- * class MyActor extends Actor {
- * def act() {
- * // actor behavior goes here
- * }
- * }
- * }}}
- * A new `Actor` instance is started by invoking its `start` method.
- *
- * '''Note:''' care must be taken when invoking thread-blocking methods other
- * than those provided by the `Actor` trait or its companion object (such as
- * `receive`). Blocking the underlying thread inside an actor may lead to
- * starvation of other actors. This also applies to actors hogging their
- * thread for a long time between invoking `receive`/`react`.
- *
- * If actors use blocking operations (for example, methods for blocking I/O),
- * there are several options:
- *
- * - The run-time system can be configured to use a larger thread pool size
- * (for example, by setting the `actors.corePoolSize` JVM property).
- * - The `scheduler` method of the `Actor` trait can be overridden to return a
- * `ResizableThreadPoolScheduler`, which resizes its thread pool to
- * avoid starvation caused by actors that invoke arbitrary blocking methods.
- * - The `actors.enableForkJoin` JVM property can be set to `false`, in which
- * case a `ResizableThreadPoolScheduler` is used by default to execute actors.
- *
- * The main ideas of the implementation are explained in the two papers
- *
- * - [[http://lampwww.epfl.ch/~odersky/papers/jmlc06.pdf Event-Based
- * Programming without Inversion of Control]],
- * Philipp Haller and Martin Odersky, ''Proc. JMLC 2006'', and
- * - [[http://lamp.epfl.ch/~phaller/doc/haller07coord.pdf Actors that
- * Unify Threads and Events]],
- * Philipp Haller and Martin Odersky, ''Proc. COORDINATION 2007''.
- *
- * @author Philipp Haller
- *
- * @define actor actor
- * @define channel actor's mailbox
- */
-@SerialVersionUID(-781154067877019505L)
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-trait Actor extends InternalActor with ReplyReactor {
-
- override def start(): Actor = synchronized {
- super.start()
- this
- }
-
- }
-
diff --git a/src/actors/scala/actors/ActorCanReply.scala b/src/actors/scala/actors/ActorCanReply.scala
deleted file mode 100644
index 07191ec65c..0000000000
--- a/src/actors/scala/actors/ActorCanReply.scala
+++ /dev/null
@@ -1,66 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-package scala.actors
-
-import scala.concurrent.SyncVar
-
-/**
- * Provides message send operations that
- * may result in a response from the receiver.
- *
- * @author Philipp Haller
- */
-private[actors] trait ActorCanReply extends ReactorCanReply {
- this: AbstractActor with InternalReplyReactor =>
-
- override def !?(msg: Any): Any = {
- val replyCh = new Channel[Any](Actor.self(scheduler))
- send(msg, replyCh)
- replyCh.?
- }
-
- override def !?(msec: Long, msg: Any): Option[Any] = {
- val replyCh = new Channel[Any](Actor.self(scheduler))
- send(msg, replyCh)
- replyCh.receiveWithin(msec) {
- case TIMEOUT => None
- case x => Some(x)
- }
- }
-
- override def !![A](msg: Any, handler: PartialFunction[Any, A]): Future[A] = {
- val c = new Channel[A](Actor.self(scheduler))
- val fun = (res: SyncVar[A]) => {
- val ftch = new Channel[A](Actor.self(scheduler))
- send(msg, new OutputChannel[Any] {
- def !(msg: Any) =
- ftch ! handler(msg)
- def send(msg: Any, replyTo: OutputChannel[Any]) =
- ftch.send(handler(msg), replyTo)
- def forward(msg: Any) =
- ftch.forward(handler(msg))
- def receiver =
- ftch.receiver
- })
- ftch.react {
- case any => res.set(any)
- }
- }
- val a = new FutureActor[A](fun, c)
- a.start()
- a
- }
-
- override def !!(msg: Any): Future[Any] = {
- val noTransform: PartialFunction[Any, Any] = { case x => x }
- this !! (msg, noTransform)
- }
-
-}
diff --git a/src/actors/scala/actors/ActorProxy.scala b/src/actors/scala/actors/ActorProxy.scala
deleted file mode 100644
index 5e1d3e61de..0000000000
--- a/src/actors/scala/actors/ActorProxy.scala
+++ /dev/null
@@ -1,34 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-package scala.actors
-
-import java.lang.Thread
-
-/**
- * Provides a dynamic actor proxy for normal Java threads.
- *
- * @author Philipp Haller
- */
-private[actors] class ActorProxy(t: Thread, override final val scheduler: IScheduler) extends Actor {
-
- def act() {}
-
- /**
- * Terminates with exit reason `'normal`.
- */
- override def exit(): Nothing = {
- shouldExit = false
- // links
- if (!links.isEmpty)
- exitLinked()
- throw new InterruptedException
- }
-
-}
diff --git a/src/actors/scala/actors/ActorRef.scala b/src/actors/scala/actors/ActorRef.scala
deleted file mode 100644
index 0da167aede..0000000000
--- a/src/actors/scala/actors/ActorRef.scala
+++ /dev/null
@@ -1,53 +0,0 @@
-package scala.actors
-
-import java.util.concurrent.TimeoutException
-import scala.concurrent.duration.Duration
-
-/**
- * Trait used for migration of Scala actors to Akka.
- */
-@deprecated("ActorRef ought to be used only with the Actor Migration Kit.", "2.10.0")
-trait ActorRef {
-
- /**
- * Sends a one-way asynchronous message. E.g. fire-and-forget semantics.
- * <p/>
- *
- * If invoked from within an actor then the actor reference is implicitly passed on as the implicit 'sender' argument.
- * <p/>
- *
- * This actor 'sender' reference is then available in the receiving actor in the 'sender' member variable,
- * if invoked from within an Actor. If not then no sender is available.
- * <pre>
- * actor ! message
- * </pre>
- * <p/>
- */
- def !(message: Any)(implicit sender: ActorRef = null): Unit
-
- /**
- * Sends a message asynchronously, returning a future which may eventually hold the reply.
- */
- private[actors] def ?(message: Any, timeout: Duration): scala.concurrent.Future[Any]
-
- /**
- * Forwards the message and passes the original sender actor as the sender.
- * <p/>
- * Works with '!' and '?'.
- */
- def forward(message: Any)
-
- private[actors] def localActor: AbstractActor
-
-}
-
-/**
- * This is what is used to complete a Future that is returned from an ask/? call,
- * when it times out.
- */
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-class AskTimeoutException(message: String, cause: Throwable) extends TimeoutException {
- def this(message: String) = this(message, null: Throwable)
-}
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-object PoisonPill
diff --git a/src/actors/scala/actors/ActorTask.scala b/src/actors/scala/actors/ActorTask.scala
deleted file mode 100644
index 21d7a0a1ad..0000000000
--- a/src/actors/scala/actors/ActorTask.scala
+++ /dev/null
@@ -1,60 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.actors
-
-/**
- * @author Philipp Haller
- * @note This class inherits a public var called 'msg' from ReactorTask,
- * and also defines a constructor parameter which shadows it (which makes any
- * changes to the underlying var invisible.) I can't figure out what's supposed
- * to happen, so I renamed the constructor parameter to at least be less confusing.
- */
-private[actors] class ActorTask(actor: InternalActor,
- fun: () => Unit,
- handler: PartialFunction[Any, Any],
- initialMsg: Any)
- extends ReplyReactorTask(actor, fun, handler, initialMsg) {
-
- protected override def beginExecution() {
- super.beginExecution()
- actor.synchronized { // shouldExit guarded by actor
- if (actor.shouldExit)
- actor.exit()
- }
- }
-
- protected override def terminateExecution(e: Throwable) {
- val senderInfo = try { Some(actor.internalSender) } catch {
- case _: Exception => None
- }
- // !!! If this is supposed to be setting the current contents of the
- // inherited mutable var rather than always the value given in the constructor,
- // then it should be changed from initialMsg to msg.
- val uncaught = UncaughtException(actor,
- if (initialMsg != null) Some(initialMsg) else None,
- senderInfo,
- Thread.currentThread,
- e)
-
- val todo = actor.synchronized {
- val res = if (!actor.links.isEmpty)
- actor.exitLinked(uncaught)
- else {
- super.terminateExecution(e)
- () => {}
- }
- res
- }
-
- todo()
- }
-
-}
diff --git a/src/actors/scala/actors/CanReply.scala b/src/actors/scala/actors/CanReply.scala
deleted file mode 100644
index 3f2c53f423..0000000000
--- a/src/actors/scala/actors/CanReply.scala
+++ /dev/null
@@ -1,65 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala.actors
-
-import scala.language.higherKinds
-
-/**
- * Defines result-bearing message send operations.
- *
- * @author Philipp Haller
- *
- * @define actor `CanReply`
- */
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-trait CanReply[-T, +R] {
-
- type Future[+P] <: () => P
-
- /**
- * Sends `msg` to this $actor and awaits reply (synchronous).
- *
- * @param msg the message to be sent
- * @return the reply
- */
- def !?(msg: T): R
-
- /**
- * Sends `msg` to this $actor and awaits reply (synchronous) within
- * `msec` milliseconds.
- *
- * @param msec the time span before timeout
- * @param msg the message to be sent
- * @return `None` in case of timeout, otherwise
- * `Some(x)` where `x` is the reply
- */
- def !?(msec: Long, msg: T): Option[R]
-
- /**
- * Sends `msg` to this $actor and immediately returns a future representing
- * the reply value.
- *
- * @param msg the message to be sent
- * @return the future
- */
- def !!(msg: T): Future[R]
-
- /**
- * Sends `msg` to this $actor and immediately returns a future representing
- * the reply value. The reply is post-processed using the partial function
- * `handler`. This also allows to recover a more precise type for the reply
- * value.
- *
- * @param msg the message to be sent
- * @param handler the function to be applied to the response
- * @return the future
- */
- def !![P](msg: T, handler: PartialFunction[R, P]): Future[P]
-
-}
diff --git a/src/actors/scala/actors/Channel.scala b/src/actors/scala/actors/Channel.scala
deleted file mode 100644
index ddf7b329c8..0000000000
--- a/src/actors/scala/actors/Channel.scala
+++ /dev/null
@@ -1,136 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala.actors
-
-import scala.concurrent.SyncVar
-
-/**
- * Used to pattern match on values that were sent to some channel `Chan,,n,,`
- * by the current actor `self`.
- *
- * @example {{{
- * receive {
- * case Chan1 ! msg1 => ...
- * case Chan2 ! msg2 => ...
- * }
- * }}}
- *
- * @author Philipp Haller
- */
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-case class ! [a](ch: Channel[a], msg: a)
-
-/**
- * Provides a means for typed communication among actors. Only the
- * actor creating an instance of a `Channel` may receive from it.
- *
- * @author Philipp Haller
- *
- * @define actor channel
- * @define channel channel
- */
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-class Channel[Msg](val receiver: InternalActor) extends InputChannel[Msg] with OutputChannel[Msg] with CanReply[Msg, Any] {
-
- type Future[+P] = scala.actors.Future[P]
-
- def this() = this(Actor.self)
-
- def !(msg: Msg) {
- receiver ! scala.actors.!(this, msg)
- }
-
- def send(msg: Msg, replyTo: OutputChannel[Any]) {
- receiver.send(scala.actors.!(this, msg), replyTo)
- }
-
- def forward(msg: Msg) {
- receiver forward scala.actors.!(this, msg)
- }
-
- def receive[R](f: PartialFunction[Msg, R]): R = {
- val C = this.asInstanceOf[Channel[Any]]
- receiver.receive {
- case C ! msg if (f.isDefinedAt(msg.asInstanceOf[Msg])) => f(msg.asInstanceOf[Msg])
- }
- }
-
- def ? : Msg = receive {
- case x => x
- }
-
- def receiveWithin[R](msec: Long)(f: PartialFunction[Any, R]): R = {
- val C = this.asInstanceOf[Channel[Any]]
- receiver.receiveWithin(msec) {
- case C ! msg if (f.isDefinedAt(msg)) => f(msg)
- case TIMEOUT => f(TIMEOUT)
- }
- }
-
- def react(f: PartialFunction[Msg, Unit]): Nothing = {
- val C = this.asInstanceOf[Channel[Any]]
- receiver.react {
- case C ! msg if (f.isDefinedAt(msg.asInstanceOf[Msg])) => f(msg.asInstanceOf[Msg])
- }
- }
-
- def reactWithin(msec: Long)(f: PartialFunction[Any, Unit]): Nothing = {
- val C = this.asInstanceOf[Channel[Any]]
- receiver.reactWithin(msec) {
- case C ! msg if (f.isDefinedAt(msg)) => f(msg)
- case TIMEOUT => f(TIMEOUT)
- }
- }
-
- def !?(msg: Msg): Any = {
- val replyCh = new Channel[Any](Actor.self(receiver.scheduler))
- receiver.send(scala.actors.!(this, msg), replyCh)
- replyCh.receive {
- case x => x
- }
- }
-
- def !?(msec: Long, msg: Msg): Option[Any] = {
- val replyCh = new Channel[Any](Actor.self(receiver.scheduler))
- receiver.send(scala.actors.!(this, msg), replyCh)
- replyCh.receiveWithin(msec) {
- case TIMEOUT => None
- case x => Some(x)
- }
- }
-
- def !![A](msg: Msg, handler: PartialFunction[Any, A]): Future[A] = {
- val c = new Channel[A](Actor.self(receiver.scheduler))
- val fun = (res: SyncVar[A]) => {
- val ftch = new Channel[A](Actor.self(receiver.scheduler))
- receiver.send(scala.actors.!(this, msg), new OutputChannel[Any] {
- def !(msg: Any) =
- ftch ! handler(msg)
- def send(msg: Any, replyTo: OutputChannel[Any]) =
- ftch.send(handler(msg), replyTo)
- def forward(msg: Any) =
- ftch.forward(handler(msg))
- def receiver =
- ftch.receiver
- })
- ftch.react {
- case any => res.set(any)
- }
- }
- val a = new FutureActor[A](fun, c)
- a.start()
- a
- }
-
- def !!(msg: Msg): Future[Any] = {
- val noTransform: PartialFunction[Any, Any] = { case x => x }
- this !! (msg, noTransform)
- }
-
-}
diff --git a/src/actors/scala/actors/Combinators.scala b/src/actors/scala/actors/Combinators.scala
deleted file mode 100644
index 64dbaf06e4..0000000000
--- a/src/actors/scala/actors/Combinators.scala
+++ /dev/null
@@ -1,48 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.actors
-
-import scala.language.implicitConversions
-
-private[actors] trait Combinators {
-
- /**
- * Enables the composition of suspendable closures using `andThen`,
- * `loop`, `loopWhile`, etc.
- */
- implicit def mkBody[a](body: => a): InternalActor.Body[a]
-
- /**
- * Repeatedly executes `body`.
- *
- * @param body the block to be executed
- */
- def loop(body: => Unit): Unit = body andThen loop(body)
-
- /**
- * Repeatedly executes `body` while the condition `cond` is `true`.
- *
- * @param cond the condition to test
- * @param body the block to be executed
- */
- def loopWhile(cond: => Boolean)(body: => Unit): Unit =
- if (cond) { body andThen loopWhile(cond)(body) }
- else continue
-
- /**
- * Continues with the execution of the closure registered as
- * continuation following `andThen`. Continues with the execution
- * of the next loop iteration when invoked inside the body of `loop`
- * or `loopWhile`.
- */
- def continue(): Unit = throw new KillActorControl
-
-}
diff --git a/src/actors/scala/actors/DaemonActor.scala b/src/actors/scala/actors/DaemonActor.scala
deleted file mode 100644
index 04a4b4a40c..0000000000
--- a/src/actors/scala/actors/DaemonActor.scala
+++ /dev/null
@@ -1,24 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala.actors
-
-import scheduler.DaemonScheduler
-
-/**
- * Base trait for actors with daemon semantics.
- *
- * Unlike a regular `Actor`, an active `DaemonActor` will not
- * prevent an application terminating, much like a daemon thread.
- *
- * @author Erik Engbrecht
- */
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-trait DaemonActor extends Actor {
- override def scheduler: IScheduler = DaemonScheduler
-}
diff --git a/src/actors/scala/actors/Debug.scala b/src/actors/scala/actors/Debug.scala
deleted file mode 100644
index 31ef53bdbe..0000000000
--- a/src/actors/scala/actors/Debug.scala
+++ /dev/null
@@ -1,45 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-package scala.actors
-
-/**
- * Provides methods for generating debugging output.
- *
- * @author Philipp Haller
- */
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-object Debug extends Logger("") {}
-
-private[actors] class Logger(tag: String) {
- private var lev = 2
-
- def level = lev
- def level_= (lev: Int) = { this.lev = lev }
-
- private val tagString = if (tag == "") "" else " ["+tag+"]"
-
- def info(s: String) =
- if (lev > 2) System.out.println("Info" + tagString + ": " + s)
-
- def warning(s: String) =
- if (lev > 1) System.err.println("Warning" + tagString + ": " + s)
-
- def error(s: String) =
- if (lev > 0) System.err.println("Error" + tagString + ": " + s)
-
- def doInfo(b: => Unit) =
- if (lev > 2) b
-
- def doWarning(b: => Unit) =
- if (lev > 1) b
-
- def doError(b: => Unit) =
- if (lev > 0) b
-}
diff --git a/src/actors/scala/actors/Future.scala b/src/actors/scala/actors/Future.scala
deleted file mode 100644
index 4421c7a07a..0000000000
--- a/src/actors/scala/actors/Future.scala
+++ /dev/null
@@ -1,243 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-package scala.actors
-
-import scala.actors.scheduler.DaemonScheduler
-import scala.concurrent.SyncVar
-
-/** A function of arity 0, returing a value of type `T` that,
- * when applied, blocks the current actor (`Actor.self`)
- * until the future's value is available.
- *
- * A future can be queried to find out whether its value
- * is already available without blocking.
- *
- * @author Philipp Haller
- */
-@deprecated("Use the scala.concurrent.Future instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-abstract class Future[+T] extends Responder[T] with Function0[T] {
-
- @volatile
- private[actors] var fvalue: Option[Any] = None
- private[actors] def fvalueTyped = fvalue.get.asInstanceOf[T]
-
- /** Tests whether the future's result is available.
- *
- * @return `true` if the future's result is available,
- * `false` otherwise.
- */
- def isSet: Boolean
-
- /** Returns an input channel that can be used to receive the future's result.
- *
- * @return the future's input channel
- */
- def inputChannel: InputChannel[T]
-
-}
-
-private case object Eval
-
-private class FutureActor[T](fun: SyncVar[T] => Unit, channel: Channel[T]) extends Future[T] with DaemonActor {
-
- var enableChannel = false // guarded by this
-
- def isSet = !fvalue.isEmpty
-
- def apply(): T = {
- if (fvalue.isEmpty) {
- this !? Eval
- }
- fvalueTyped
- }
-
- def respond(k: T => Unit) {
- if (isSet) k(fvalueTyped)
- else {
- val ft = this !! Eval
- ft.inputChannel.react {
- case _ => k(fvalueTyped)
- }
- }
- }
-
- def inputChannel: InputChannel[T] = {
- synchronized {
- if (!enableChannel) {
- if (isSet)
- channel ! fvalueTyped
- enableChannel = true
- }
- }
- channel
- }
-
- def act() {
- val res = new SyncVar[T]
-
- {
- fun(res)
- } andThen {
-
- synchronized {
- val v = res.get
- fvalue = Some(v)
- if (enableChannel)
- channel ! v
- }
-
- loop {
- react {
- // This is calling ReplyReactor#reply(msg: Any).
- // Was: reply(). Now: reply(()).
- case Eval => reply(())
- }
- }
- }
- }
-}
-
-/** Methods that operate on futures.
- *
- * @author Philipp Haller
- */
-@deprecated("Use the object scala.concurrent.Future instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-object Futures {
-
- /** Arranges for the asynchronous execution of `body`,
- * returning a future representing the result.
- *
- * @param body the computation to be carried out asynchronously
- * @return the future representing the result of the
- * computation
- */
- def future[T](body: => T): Future[T] = {
- val c = new Channel[T](Actor.self(DaemonScheduler))
- val a = new FutureActor[T](_.set(body), c)
- a.start()
- a
- }
-
- /** Creates a future that resolves after a given time span.
- *
- * @param timespan the time span in ms after which the future resolves
- * @return the future
- */
- def alarm(timespan: Long): Future[Unit] = {
- val c = new Channel[Unit](Actor.self(DaemonScheduler))
- val fun = (res: SyncVar[Unit]) => {
- Actor.reactWithin(timespan) {
- case TIMEOUT => res.set({})
- }
- }
- val a = new FutureActor[Unit](fun, c)
- a.start()
- a
- }
-
- /** Waits for the first result returned by one of two
- * given futures.
- *
- * @param ft1 the first future
- * @param ft2 the second future
- * @return the result of the future that resolves first
- */
- def awaitEither[A, B >: A](ft1: Future[A], ft2: Future[B]): B = {
- val FutCh1 = ft1.inputChannel
- val FutCh2 = ft2.inputChannel
- Actor.receive {
- case FutCh1 ! arg1 => arg1.asInstanceOf[B]
- case FutCh2 ! arg2 => arg2.asInstanceOf[B]
- }
- }
-
- /** Waits until either all futures are resolved or a given
- * time span has passed. Results are collected in a list of
- * options. The result of a future that resolved during the
- * time span is its value wrapped in `Some`. The result of a
- * future that did not resolve during the time span is `None`.
- *
- * Note that some of the futures might already have been awaited,
- * in which case their value is returned wrapped in `Some`.
- * Passing a timeout of 0 causes `awaitAll` to return immediately.
- *
- * @param timeout the time span in ms after which waiting is
- * aborted
- * @param fts the futures to be awaited
- * @return the list of optional future values
- * @throws java.lang.IllegalArgumentException if timeout is negative,
- * or timeout + `System.currentTimeMillis()` is negative.
- */
- def awaitAll(timeout: Long, fts: Future[Any]*): List[Option[Any]] = {
- val resultsMap: scala.collection.mutable.Map[Int, Option[Any]] = new scala.collection.mutable.HashMap[Int, Option[Any]]
-
- var cnt = 0
- val mappedFts = fts.map(ft =>
- ({cnt+=1; cnt-1}, ft))
-
- val unsetFts = mappedFts.filter((p: Tuple2[Int, Future[Any]]) => {
- if (p._2.isSet) { resultsMap(p._1) = Some(p._2()); false }
- else { resultsMap(p._1) = None; true }
- })
-
- val partFuns = unsetFts.map((p: Tuple2[Int, Future[Any]]) => {
- val FutCh = p._2.inputChannel
- val singleCase: PartialFunction[Any, Tuple2[Int, Any]] = {
- case FutCh ! any => (p._1, any)
- }
- singleCase
- })
-
- val thisActor = Actor.self
- val timerTask = new java.util.TimerTask {
- def run() { thisActor ! TIMEOUT }
- }
- Actor.timer.schedule(timerTask, timeout)
-
- def awaitWith(partFuns: Seq[PartialFunction[Any, Tuple2[Int, Any]]]) {
- val reaction: PartialFunction[Any, Unit] = new PartialFunction[Any, Unit] {
- def isDefinedAt(msg: Any) = msg match {
- case TIMEOUT => true
- case _ => partFuns exists (_ isDefinedAt msg)
- }
- def apply(msg: Any): Unit = msg match {
- case TIMEOUT => // do nothing
- case _ => {
- val pfOpt = partFuns find (_ isDefinedAt msg)
- val pf = pfOpt.get // succeeds always
- val (idx, subres) = pf(msg)
- resultsMap(idx) = Some(subres)
-
- val partFunsRest = partFuns filter (_ != pf)
- // wait on rest of partial functions
- if (partFunsRest.length > 0)
- awaitWith(partFunsRest)
- }
- }
- }
- Actor.receive(reaction)
- }
-
- if (partFuns.length > 0)
- awaitWith(partFuns)
-
- var results: List[Option[Any]] = Nil
- val size = resultsMap.size
- for (i <- 0 until size) {
- results = resultsMap(size - i - 1) :: results
- }
-
- // cancel scheduled timer task
- timerTask.cancel()
-
- results
- }
-
-}
diff --git a/src/actors/scala/actors/IScheduler.scala b/src/actors/scala/actors/IScheduler.scala
deleted file mode 100644
index 9d61d48561..0000000000
--- a/src/actors/scala/actors/IScheduler.scala
+++ /dev/null
@@ -1,70 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-package scala.actors
-
-/**
- * A common interface for all schedulers used to execute actor tasks.
- *
- * Subclasses of `Actor` that override its `scheduler` member must provide
- * an `IScheduler` implementation.
- *
- * @author Philipp Haller
- */
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-trait IScheduler {
-
- /** Submits a closure for execution.
- *
- * @param fun the closure to be executed
- */
- def execute(fun: => Unit): Unit
-
- /** Submits a `Runnable` for execution.
- *
- * @param task the task to be executed
- */
- def execute(task: Runnable): Unit
-
- def executeFromActor(task: Runnable): Unit =
- execute(task)
-
- /** Shuts down the scheduler. */
- def shutdown(): Unit
-
- /** When the scheduler is active, it can execute tasks.
- *
- * @return `'''true'''`, if the scheduler is active, otherwise false.
- */
- def isActive: Boolean
-
- /** Registers a newly created actor with this scheduler.
- *
- * @param a the actor to be registered
- */
- def newActor(a: TrackedReactor): Unit
-
- /** Unregisters an actor from this scheduler, because it
- * has terminated.
- *
- * @param a the actor to be registered
- */
- def terminated(a: TrackedReactor): Unit
-
- /** Registers a closure to be executed when the specified
- * actor terminates.
- *
- * @param a the actor
- * @param f the closure to be registered
- */
- def onTerminate(a: TrackedReactor)(f: => Unit): Unit
-
- def managedBlock(blocker: scala.concurrent.ManagedBlocker): Unit
-
-}
diff --git a/src/actors/scala/actors/InputChannel.scala b/src/actors/scala/actors/InputChannel.scala
deleted file mode 100644
index d2dd6d24df..0000000000
--- a/src/actors/scala/actors/InputChannel.scala
+++ /dev/null
@@ -1,66 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-package scala.actors
-
-/**
- * A common interface for all channels from which values can be received.
- *
- * @author Philipp Haller
- *
- * @define channel `InputChannel`
- */
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-trait InputChannel[+Msg] {
-
- /**
- * Receives a message from this $channel.
- *
- * @param f a partial function with message patterns and actions
- * @return result of processing the received value
- */
- def receive[R](f: PartialFunction[Msg, R]): R
-
- /**
- * Receives a message from this $channel within
- * a certain time span.
- *
- * @param msec the time span before timeout
- * @param f a partial function with message patterns and actions
- * @return result of processing the received value
- */
- def receiveWithin[R](msec: Long)(f: PartialFunction[Any, R]): R
-
- /**
- * Receives a message from this $channel.
- *
- * This method never returns. Therefore, the rest of the computation
- * has to be contained in the actions of the partial function.
- *
- * @param f a partial function with message patterns and actions
- */
- def react(f: PartialFunction[Msg, Unit]): Nothing
-
- /**
- * Receives a message from this $channel within
- * a certain time span.
- *
- * This method never returns. Therefore, the rest of the computation
- * has to be contained in the actions of the partial function.
- *
- * @param msec the time span before timeout
- * @param f a partial function with message patterns and actions
- */
- def reactWithin(msec: Long)(f: PartialFunction[Any, Unit]): Nothing
-
- /**
- * Receives the next message from this $channel.
- */
- def ? : Msg
-}
diff --git a/src/actors/scala/actors/InternalActor.scala b/src/actors/scala/actors/InternalActor.scala
deleted file mode 100644
index 5045ea56e8..0000000000
--- a/src/actors/scala/actors/InternalActor.scala
+++ /dev/null
@@ -1,546 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-package scala.actors
-import java.util.TimerTask
-import scala.util.control.ControlThrowable
-
-private[actors] object InternalActor {
- private[actors] trait Body[a] {
- def andThen[b](other: => b): Unit
- }
-}
-
-private[actors] trait InternalActor extends AbstractActor with InternalReplyReactor with ActorCanReply with InputChannel[Any] with Serializable {
-
- /* The following two fields are only used when the actor
- * suspends by blocking its underlying thread, for example,
- * when waiting in a receive or synchronous send.
- */
- @volatile
- private[actors] var isSuspended = false
-
- /* This field is used to communicate the received message from
- * the invocation of send to the place where the thread of
- * the receiving actor resumes inside receive/receiveWithin.
- */
- @volatile
- private var received: Option[Any] = None
-
- protected[actors] override def scheduler: IScheduler = Scheduler
-
- private[actors] override def startSearch(msg: Any, replyTo: OutputChannel[Any], handler: PartialFunction[Any, Any]) =
- if (isSuspended) {
- () =>
- synchronized {
- mailbox.append(msg, replyTo)
- resumeActor()
- }
- } else super.startSearch(msg, replyTo, handler)
-
- // we override this method to check `shouldExit` before suspending
- private[actors] override def searchMailbox(startMbox: MQueue[Any],
- handler: PartialFunction[Any, Any],
- resumeOnSameThread: Boolean) {
- var tmpMbox = startMbox
- var done = false
- while (!done) {
- val qel = tmpMbox.extractFirst((msg: Any, replyTo: OutputChannel[Any]) => {
- senders = List(replyTo)
- handler.isDefinedAt(msg)
- })
- if (tmpMbox ne mailbox)
- tmpMbox.foreach((m, s) => mailbox.append(m, s))
- if (null eq qel) {
- synchronized {
- // in mean time new stuff might have arrived
- if (!sendBuffer.isEmpty) {
- tmpMbox = new MQueue[Any]("Temp")
- drainSendBuffer(tmpMbox)
- // keep going
- } else {
- // very important to check for `shouldExit` at this point
- // since linked actors might have set it after we checked
- // last time (e.g., at the beginning of `react`)
- if (shouldExit) exit()
- waitingFor = handler
- // see Reactor.searchMailbox
- throw Actor.suspendException
- }
- }
- } else {
- resumeReceiver((qel.msg, qel.session), handler, resumeOnSameThread)
- done = true
- }
- }
- }
-
- private[actors] override def makeReaction(fun: () => Unit, handler: PartialFunction[Any, Any], msg: Any): Runnable =
- new ActorTask(this, fun, handler, msg)
-
- /** See the companion object's `receive` method. */
- def receive[R](f: PartialFunction[Any, R]): R = {
- assert(Actor.self(scheduler) == this, "receive from channel belonging to other actor")
-
- synchronized {
- if (shouldExit) exit() // links
- drainSendBuffer(mailbox)
- }
-
- var done = false
- while (!done) {
- val qel = mailbox.extractFirst((m: Any, replyTo: OutputChannel[Any]) => {
- senders = replyTo :: senders
- val matches = f.isDefinedAt(m)
- senders = senders.tail
- matches
- })
- if (null eq qel) {
- synchronized {
- // in mean time new stuff might have arrived
- if (!sendBuffer.isEmpty) {
- drainSendBuffer(mailbox)
- // keep going
- } else {
- waitingFor = f
- isSuspended = true
- scheduler.managedBlock(blocker)
- drainSendBuffer(mailbox)
- // keep going
- }
- }
- } else {
- received = Some(qel.msg)
- senders = qel.session :: senders
- done = true
- }
- }
-
- val result = f(received.get)
- received = None
- senders = senders.tail
- result
- }
-
- /** See the companion object's `receiveWithin` method. */
- def receiveWithin[R](msec: Long)(f: PartialFunction[Any, R]): R = {
- assert(Actor.self(scheduler) == this, "receive from channel belonging to other actor")
-
- synchronized {
- if (shouldExit) exit() // links
- drainSendBuffer(mailbox)
- }
-
- // first, remove spurious TIMEOUT message from mailbox if any
- mailbox.extractFirst((m: Any, replyTo: OutputChannel[Any]) => m == TIMEOUT)
-
- val receiveTimeout = () => {
- if (f.isDefinedAt(TIMEOUT)) {
- received = Some(TIMEOUT)
- senders = this :: senders
- } else
- sys.error("unhandled timeout")
- }
-
- var done = false
- while (!done) {
- val qel = mailbox.extractFirst((m: Any, replyTo: OutputChannel[Any]) => {
- senders = replyTo :: senders
- val matches = f.isDefinedAt(m)
- senders = senders.tail
- matches
- })
- if (null eq qel) {
- val todo = synchronized {
- // in mean time new stuff might have arrived
- if (!sendBuffer.isEmpty) {
- drainSendBuffer(mailbox)
- // keep going
- () => {}
- } else if (msec == 0L) {
- done = true
- receiveTimeout
- } else {
- if (onTimeout.isEmpty) {
- if (!f.isDefinedAt(TIMEOUT))
- sys.error("unhandled timeout")
-
- val thisActor = this
- onTimeout = Some(new TimerTask {
- def run() {
- thisActor.send(TIMEOUT, thisActor)
- }
- })
- Actor.timer.schedule(onTimeout.get, msec)
- }
-
- // It is possible that !onTimeout.isEmpty, but TIMEOUT is not yet in mailbox
- // See SI-4759
- waitingFor = f
- received = None
- isSuspended = true
- scheduler.managedBlock(blocker)
- drainSendBuffer(mailbox)
- // keep going
- () => {}
- }
- }
- todo()
- } else {
- synchronized {
- if (!onTimeout.isEmpty) {
- onTimeout.get.cancel()
- onTimeout = None
- }
- }
- received = Some(qel.msg)
- senders = qel.session :: senders
- done = true
- }
- }
-
- val result = f(received.get)
- received = None
- senders = senders.tail
- result
- }
-
- /** See the companion object's `react` method. */
- override def react(handler: PartialFunction[Any, Unit]): Nothing = {
- synchronized {
- if (shouldExit) exit()
- }
- super.react(handler)
- }
-
- /** See the companion object's `reactWithin` method. */
- override def reactWithin(msec: Long)(handler: PartialFunction[Any, Unit]): Nothing = {
- synchronized {
- if (shouldExit) exit()
- }
- super.reactWithin(msec)(handler)
- }
-
- /** Receives the next message from the mailbox */
- def ? : Any = receive {
- case x => x
- }
-
- // guarded by lock of this
- // never throws SuspendActorControl
- private[actors] override def scheduleActor(f: PartialFunction[Any, Any], msg: Any) =
- if (f eq null) {
- // do nothing (timeout is handled instead)
- } else {
- val task = new ActorTask(this, null, f, msg)
- scheduler executeFromActor task
- }
-
- /* Used for notifying scheduler when blocking inside receive/receiveWithin. */
- private object blocker extends scala.concurrent.ManagedBlocker {
- def block() = {
- InternalActor.this.suspendActor()
- true
- }
- def isReleasable =
- !InternalActor.this.isSuspended
- }
-
- private def suspendActor() = synchronized {
- while (isSuspended) {
- try {
- wait()
- } catch {
- case _: InterruptedException =>
- }
- }
- // links: check if we should exit
- if (shouldExit) exit()
- }
-
- private def resumeActor() {
- isSuspended = false
- notify()
- }
-
- private[actors] override def exiting = synchronized {
- _state == Actor.State.Terminated
- }
-
- // guarded by this
- private[actors] override def dostart() {
- // Reset various flags.
- //
- // Note that we do *not* reset `trapExit`. The reason is that
- // users should be able to set the field in the constructor
- // and before `act` is called.
- exitReason = 'normal
- shouldExit = false
-
- super.dostart()
- }
-
- override def start(): InternalActor = synchronized {
- super.start()
- this
- }
-
- /** State of this actor */
- override def getState: Actor.State.Value = synchronized {
- if (isSuspended) {
- if (onTimeout.isEmpty)
- Actor.State.Blocked
- else
- Actor.State.TimedBlocked
- } else
- super.getState
- }
-
- // guarded by this
- private[actors] var links: List[AbstractActor] = Nil
-
- /**
- * Links <code>self</code> to actor <code>to</code>.
- *
- * @param to the actor to link to
- * @return the parameter actor
- */
- def link(to: AbstractActor): AbstractActor = {
- assert(Actor.self(scheduler) == this, "link called on actor different from self")
- this linkTo to
- to linkTo this
- to
- }
-
- /**
- * Links <code>self</code> to actor <code>to</code>.
- *
- * @param to the actor to link to
- * @return the parameter actor
- */
- def link(to: ActorRef): ActorRef = {
- this.link(to.localActor)
- to
- }
-
- /**
- * Unidirectional linking. For migration purposes only
- */
- private[actors] def watch(subject: ActorRef): ActorRef = {
- assert(Actor.self(scheduler) == this, "link called on actor different from self")
- subject.localActor linkTo this
- subject
- }
-
- /**
- * Unidirectional linking. For migration purposes only
- */
- private[actors] def unwatch(subject: ActorRef): ActorRef = {
- assert(Actor.self(scheduler) == this, "link called on actor different from self")
- subject.localActor unlinkFrom this
- subject
- }
-
- /**
- * Links <code>self</code> to the actor defined by <code>body</code>.
- *
- * @param body the body of the actor to link to
- * @return the parameter actor
- */
- def link(body: => Unit): Actor = {
- assert(Actor.self(scheduler) == this, "link called on actor different from self")
- val a = new Actor {
- def act() = body
- override final val scheduler: IScheduler = InternalActor.this.scheduler
- }
- link(a)
- a.start()
- a
- }
-
- private[actors] def linkTo(to: AbstractActor) = synchronized {
- links = to :: links
- }
-
- /**
- * Unlinks <code>self</code> from actor <code>from</code>.
- */
- def unlink(from: AbstractActor) {
- assert(Actor.self(scheduler) == this, "unlink called on actor different from self")
- this unlinkFrom from
- from unlinkFrom this
- }
-
- /**
- * Unlinks <code>self</code> from actor <code>from</code>.
- */
- def unlink(from: ActorRef) {
- unlink(from.localActor)
- }
-
- private[actors] def unlinkFrom(from: AbstractActor) = synchronized {
- links = links.filterNot(from.==)
- }
-
- @volatile
- private[actors] var _trapExit = false
-
- def trapExit = _trapExit
-
- def trapExit_=(value: Boolean) = _trapExit = value
-
- // guarded by this
- private var exitReason: AnyRef = 'normal
- // guarded by this
- private[actors] var shouldExit = false
-
- /**
- * <p>
- * Terminates execution of <code>self</code> with the following
- * effect on linked actors:
- * </p>
- * <p>
- * For each linked actor <code>a</code> with
- * <code>trapExit</code> set to <code>true</code>, send message
- * <code>Exit(self, reason)</code> to <code>a</code>.
- * </p>
- * <p>
- * For each linked actor <code>a</code> with
- * <code>trapExit</code> set to <code>false</code> (default),
- * call <code>a.exit(reason)</code> if
- * <code>reason != 'normal</code>.
- * </p>
- */
- protected[actors] def exit(reason: AnyRef): Nothing = {
- synchronized {
- exitReason = reason
- }
- exit()
- }
-
- /**
- * Terminates with exit reason <code>'normal</code>.
- */
- protected[actors] override def exit(): Nothing = {
- val todo = synchronized {
- if (!links.isEmpty)
- exitLinked()
- else
- () => {}
- }
- todo()
- super.exit()
- }
-
- // Assume !links.isEmpty
- // guarded by this
- private[actors] def exitLinked(): () => Unit = {
- _state = Actor.State.Terminated
- // reset waitingFor, otherwise getState returns Suspended
- waitingFor = Reactor.waitingForNone
- // remove this from links
- val mylinks = links.filterNot(this.==)
- // unlink actors
- mylinks.foreach(unlinkFrom(_))
- // return closure that locks linked actors
- () => {
- mylinks.foreach((linked: AbstractActor) => {
- linked.synchronized {
- if (!linked.exiting) {
- linked.unlinkFrom(this)
- linked.exit(this, exitReason)
- }
- }
- })
- }
- }
-
- // Assume !links.isEmpty
- // guarded by this
- private[actors] def exitLinked(reason: AnyRef): () => Unit = {
- exitReason = reason
- exitLinked()
- }
-
- // Assume !this.exiting
- private[actors] def exit(from: AbstractActor, reason: AnyRef) {
- if (trapExit) {
- this ! Exit(from, reason)
- } else if (reason != 'normal)
- stop(reason)
- }
-
- /* Requires qualified private, because <code>RemoteActor</code> must
- * register a termination handler.
- */
- private[actors] def onTerminate(f: => Unit) {
- scheduler.onTerminate(this) { f }
- }
-
-
- private[actors] def stop(reason: AnyRef): Unit = {
- synchronized {
- shouldExit = true
- exitReason = reason
- // resume this Actor in a way that
- // causes it to exit
- // (because shouldExit == true)
- if (isSuspended)
- resumeActor()
- else if (waitingFor ne Reactor.waitingForNone) {
- waitingFor = Reactor.waitingForNone
- // it doesn't matter what partial function we are passing here
- val task = new ActorTask(this, null, waitingFor, null)
- scheduler execute task
- /* Here we should not throw a SuspendActorControl,
- since the current method is called from an actor that
- is in the process of exiting.
-
- Therefore, the contract for scheduleActor is that
- it never throws a SuspendActorControl.
- */
- }
- }
- }
-}
-
-/**
- * Used as the timeout pattern in
- * <a href="Actor.html#receiveWithin(Long)" target="contentFrame">
- * <code>receiveWithin</code></a> and
- * <a href="Actor.html#reactWithin(Long)" target="contentFrame">
- * <code>reactWithin</code></a>.
- *
- * @example {{{
- * receiveWithin(500) {
- * case (x, y) => ...
- * case TIMEOUT => ...
- * }
- * }}}
- *
- * @author Philipp Haller
- */
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-case object TIMEOUT
-
-/**
- * Sent to an actor
- * with `trapExit` set to `true` whenever one of its linked actors
- * terminates.
- *
- * @param from the actor that terminated
- * @param reason the reason that caused the actor to terminate
- */
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-case class Exit(from: AbstractActor, reason: AnyRef)
-
-/**
- * Manages control flow of actor executions.
- *
- * @author Philipp Haller
- */
-private[actors] class SuspendActorControl extends ControlThrowable
diff --git a/src/actors/scala/actors/InternalReplyReactor.scala b/src/actors/scala/actors/InternalReplyReactor.scala
deleted file mode 100644
index c744984fd8..0000000000
--- a/src/actors/scala/actors/InternalReplyReactor.scala
+++ /dev/null
@@ -1,162 +0,0 @@
-package scala.actors
-
-import java.util.{TimerTask}
-
-/**
- * Extends the [[scala.actors.Reactor]]
- * trait with methods to reply to the sender of a message.
- * Sending a message to a <code>ReplyReactor</code> implicitly
- * passes a reference to the sender together with the message.
- *
- * @author Philipp Haller
- *
- * @define actor `ReplyReactor`
- */
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-trait InternalReplyReactor extends Reactor[Any] with ReactorCanReply {
-
- /* A list of the current senders. The head of the list is
- * the sender of the message that was received last.
- */
- @volatile
- private[actors] var senders: List[OutputChannel[Any]] = List()
-
- /* This option holds a TimerTask when the actor waits in a
- * reactWithin. The TimerTask is cancelled when the actor
- * resumes.
- *
- * guarded by this
- */
- private[actors] var onTimeout: Option[TimerTask] = None
-
- /**
- * Returns the $actor which sent the last received message.
- */
- protected[actors] def internalSender: OutputChannel[Any] = senders.head
-
- /**
- * Replies with <code>msg</code> to the sender.
- */
- protected[actors] def reply(msg: Any) {
- internalSender ! msg
- }
-
- override def !(msg: Any) {
- send(msg, Actor.rawSelf(scheduler))
- }
-
- override def forward(msg: Any) {
- send(msg, Actor.sender)
- }
-
- private[actors] override def resumeReceiver(item: (Any, OutputChannel[Any]), handler: PartialFunction[Any, Any], onSameThread: Boolean) {
- synchronized {
- if (!onTimeout.isEmpty) {
- onTimeout.get.cancel()
- onTimeout = None
- }
- }
- senders = List(item._2)
- super.resumeReceiver(item, handler, onSameThread)
- }
-
- private[actors] override def searchMailbox(startMbox: MQueue[Any],
- handler: PartialFunction[Any, Any],
- resumeOnSameThread: Boolean) {
- var tmpMbox = startMbox
- var done = false
- while (!done) {
- val qel = tmpMbox.extractFirst((msg: Any, replyTo: OutputChannel[Any]) => {
- senders = List(replyTo)
- handler.isDefinedAt(msg)
- })
- if (tmpMbox ne mailbox)
- tmpMbox.foreach((m, s) => mailbox.append(m, s))
- if (null eq qel) {
- synchronized {
- // in mean time new stuff might have arrived
- if (!sendBuffer.isEmpty) {
- tmpMbox = new MQueue[Any]("Temp")
- drainSendBuffer(tmpMbox)
- // keep going
- } else {
- waitingFor = handler
- // see Reactor.searchMailbox
- throw Actor.suspendException
- }
- }
- } else {
- resumeReceiver((qel.msg, qel.session), handler, resumeOnSameThread)
- done = true
- }
- }
- }
-
- private[actors] override def makeReaction(fun: () => Unit, handler: PartialFunction[Any, Any], msg: Any): Runnable =
- new ReplyReactorTask(this, fun, handler, msg)
-
- protected[actors] override def react(handler: PartialFunction[Any, Unit]): Nothing = {
- assert(Actor.rawSelf(scheduler) == this, "react on channel belonging to other actor")
- super.react(handler)
- }
-
-
- /**
- * Receives a message from this $actor's mailbox within a certain
- * time span.
- *
- * This method never returns. Therefore, the rest of the computation
- * has to be contained in the actions of the partial function.
- *
- * @param msec the time span before timeout
- * @param handler a partial function with message patterns and actions
- */
- protected[actors] def reactWithin(msec: Long)(handler: PartialFunction[Any, Unit]): Nothing = {
- assert(Actor.rawSelf(scheduler) == this, "react on channel belonging to other actor")
-
- synchronized { drainSendBuffer(mailbox) }
-
- // first, remove spurious TIMEOUT message from mailbox if any
- mailbox.extractFirst((m: Any, replyTo: OutputChannel[Any]) => m == TIMEOUT)
-
- while (true) {
- val qel = mailbox.extractFirst((m: Any, replyTo: OutputChannel[Any]) => {
- senders = List(replyTo)
- handler isDefinedAt m
- })
- if (null eq qel) {
- synchronized {
- // in mean time new messages might have arrived
- if (!sendBuffer.isEmpty) {
- drainSendBuffer(mailbox)
- // keep going
- } else if (msec == 0L) {
- // throws Actor.suspendException
- resumeReceiver((TIMEOUT, this), handler, false)
- } else {
- waitingFor = handler
- val thisActor = this
- onTimeout = Some(new TimerTask {
- def run() { thisActor.send(TIMEOUT, thisActor) }
- })
- Actor.timer.schedule(onTimeout.get, msec)
- throw Actor.suspendException
- }
- }
- } else
- resumeReceiver((qel.msg, qel.session), handler, false)
- }
- throw Actor.suspendException
- }
-
- override def getState: Actor.State.Value = synchronized {
- if (waitingFor ne Reactor.waitingForNone) {
- if (onTimeout.isEmpty)
- Actor.State.Suspended
- else
- Actor.State.TimedSuspended
- } else
- _state
- }
-
-}
diff --git a/src/actors/scala/actors/KillActorControl.scala b/src/actors/scala/actors/KillActorControl.scala
deleted file mode 100644
index 0f94bbc8dc..0000000000
--- a/src/actors/scala/actors/KillActorControl.scala
+++ /dev/null
@@ -1,14 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala.actors
-
-import scala.util.control.ControlThrowable
-import java.lang.{InterruptedException, Runnable}
-
-private[actors] class KillActorControl extends ControlThrowable
diff --git a/src/actors/scala/actors/LinkedNode.java b/src/actors/scala/actors/LinkedNode.java
deleted file mode 100644
index bf8ca02a74..0000000000
--- a/src/actors/scala/actors/LinkedNode.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- File: LinkedNode.java
-
- Originally written by Doug Lea and released into the public domain.
- This may be used for any purposes whatsoever without acknowledgment.
- Thanks for the assistance and support of Sun Microsystems Labs,
- and everyone contributing, testing, and using this code.
-
- History:
- Date Who What
- 11Jun1998 dl Create public version
- 25may2000 dl Change class access to public
- 26nov2001 dl Added no-arg constructor, all public access.
-*/
-
-package scala.actors;
-
-/** A standard linked list node used in various queue classes **/
-public class LinkedNode {
- public Object value;
- public LinkedNode next;
- public LinkedNode() {}
- public LinkedNode(Object x) { value = x; }
- public LinkedNode(Object x, LinkedNode n) { value = x; next = n; }
-}
diff --git a/src/actors/scala/actors/LinkedQueue.java b/src/actors/scala/actors/LinkedQueue.java
deleted file mode 100644
index 3f7b93c386..0000000000
--- a/src/actors/scala/actors/LinkedQueue.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- File: LinkedQueue.java
-
- Originally written by Doug Lea and released into the public domain.
- This may be used for any purposes whatsoever without acknowledgment.
- Thanks for the assistance and support of Sun Microsystems Labs,
- and everyone contributing, testing, and using this code.
-
- History:
- Date Who What
- 11Jun1998 dl Create public version
- 25aug1998 dl added peek
- 10dec1998 dl added isEmpty
- 10oct1999 dl lock on node object to ensure visibility
-*/
-
-package scala.actors;
-
-/**
- * A linked list based channel implementation.
- * The algorithm avoids contention between puts
- * and takes when the queue is not empty.
- * Normally a put and a take can proceed simultaneously.
- * (Although it does not allow multiple concurrent puts or takes.)
- * This class tends to perform more efficiently than
- * other Channel implementations in producer/consumer
- * applications.
- * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>]
- **/
-
-public class LinkedQueue {
-
-
- /**
- * Dummy header node of list. The first actual node, if it exists, is always
- * at head_.next. After each take, the old first node becomes the head.
- **/
- protected LinkedNode head_;
-
- /**
- * Helper monitor for managing access to last node.
- **/
- protected final Object putLock_ = new Object();
-
- /**
- * The last node of list. Put() appends to list, so modifies last_
- **/
- protected LinkedNode last_;
-
- /**
- * The number of threads waiting for a take.
- * Notifications are provided in put only if greater than zero.
- * The bookkeeping is worth it here since in reasonably balanced
- * usages, the notifications will hardly ever be necessary, so
- * the call overhead to notify can be eliminated.
- **/
- protected int waitingForTake_ = 0;
-
- public LinkedQueue() {
- head_ = new LinkedNode(null);
- last_ = head_;
- }
-
- /** Main mechanics for put/offer **/
- protected void insert(Object x) {
- synchronized(putLock_) {
- LinkedNode p = new LinkedNode(x);
- synchronized(last_) {
- last_.next = p;
- last_ = p;
- }
- if (waitingForTake_ > 0)
- putLock_.notify();
- }
- }
-
- /** Main mechanics for take/poll **/
- protected synchronized Object extract() {
- synchronized(head_) {
- Object x = null;
- LinkedNode first = head_.next;
- if (first != null) {
- x = first.value;
- first.value = null;
- head_ = first;
- }
- return x;
- }
- }
-
-
- public void put(Object x) throws InterruptedException {
- if (x == null) throw new IllegalArgumentException();
- if (Thread.interrupted()) throw new InterruptedException();
- insert(x);
- }
-
- public boolean offer(Object x, long msecs) throws InterruptedException {
- if (x == null) throw new IllegalArgumentException();
- if (Thread.interrupted()) throw new InterruptedException();
- insert(x);
- return true;
- }
-
- public Object take() throws InterruptedException {
- if (Thread.interrupted()) throw new InterruptedException();
- // try to extract. If fail, then enter wait-based retry loop
- Object x = extract();
- if (x != null)
- return x;
- else {
- synchronized(putLock_) {
- try {
- ++waitingForTake_;
- for (;;) {
- x = extract();
- if (x != null) {
- --waitingForTake_;
- return x;
- }
- else {
- putLock_.wait();
- }
- }
- }
- catch(InterruptedException ex) {
- --waitingForTake_;
- putLock_.notify();
- throw ex;
- }
- }
- }
- }
-
- public Object peek() {
- synchronized(head_) {
- LinkedNode first = head_.next;
- if (first != null)
- return first.value;
- else
- return null;
- }
- }
-
-
- public boolean isEmpty() {
- synchronized(head_) {
- return head_.next == null;
- }
- }
-
- public Object poll(long msecs) throws InterruptedException {
- if (Thread.interrupted()) throw new InterruptedException();
- Object x = extract();
- if (x != null)
- return x;
- else {
- synchronized(putLock_) {
- try {
- long waitTime = msecs;
- long start = (msecs <= 0)? 0 : System.currentTimeMillis();
- ++waitingForTake_;
- for (;;) {
- x = extract();
- if (x != null || waitTime <= 0) {
- --waitingForTake_;
- return x;
- }
- else {
- putLock_.wait(waitTime);
- waitTime = msecs - (System.currentTimeMillis() - start);
- }
- }
- }
- catch(InterruptedException ex) {
- --waitingForTake_;
- putLock_.notify();
- throw ex;
- }
- }
- }
- }
-}
-
-
diff --git a/src/actors/scala/actors/MQueue.scala b/src/actors/scala/actors/MQueue.scala
deleted file mode 100644
index d766ecc6e8..0000000000
--- a/src/actors/scala/actors/MQueue.scala
+++ /dev/null
@@ -1,250 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala.actors
-
-private[actors] class MQueueElement[Msg >: Null](val msg: Msg, val session: OutputChannel[Any], var next: MQueueElement[Msg]) {
- def this() = this(null, null, null)
- def this(msg: Msg, session: OutputChannel[Any]) = this(msg, session, null)
-}
-
-private[actors] class MQueue[Msg >: Null](protected val label: String) {
- protected var first: MQueueElement[Msg] = null
- protected var last: MQueueElement[Msg] = null // last eq null iff list is empty
- private var _size = 0
-
- def size = _size
- final def isEmpty = last eq null
-
- protected def changeSize(diff: Int) {
- _size += diff
- }
-
- def prepend(other: MQueue[Msg]) {
- if (!other.isEmpty) {
- other.last.next = first
- first = other.first
- }
- }
-
- def clear() {
- first = null
- last = null
- _size = 0
- }
-
-
- def append(msg: Msg, session: OutputChannel[Any]) {
- changeSize(1) // size always increases by 1
- val el = new MQueueElement(msg, session)
-
- if (isEmpty) first = el
- else last.next = el
-
- last = el
- }
-
- def append(el: MQueueElement[Msg]) {
- changeSize(1) // size always increases by 1
-
- if (isEmpty) first = el
- else last.next = el
-
- last = el
- }
-
- def foreach(f: (Msg, OutputChannel[Any]) => Unit) {
- var curr = first
- while (curr != null) {
- f(curr.msg, curr.session)
- curr = curr.next
- }
- }
-
- def foreachAppend(target: MQueue[Msg]) {
- var curr = first
- while (curr != null) {
- target.append(curr)
- curr = curr.next
- }
- }
-
- def foreachDequeue(target: MQueue[Msg]) {
- var curr = first
- while (curr != null) {
- target.append(curr)
- curr = curr.next
- }
- first = null
- last = null
- _size = 0
- }
-
- def foldLeft[B](z: B)(f: (B, Msg) => B): B = {
- var acc = z
- var curr = first
- while (curr != null) {
- acc = f(acc, curr.msg)
- curr = curr.next
- }
- acc
- }
-
- /** Returns the n-th message that satisfies the predicate `p`
- * without removing it.
- */
- def get(n: Int)(p: Msg => Boolean): Option[Msg] = {
- var pos = 0
-
- def test(msg: Msg): Boolean =
- p(msg) && (pos == n || { pos += 1; false })
-
- var curr = first
- while (curr != null)
- if (test(curr.msg)) return Some(curr.msg) // early return
- else curr = curr.next
-
- None
- }
-
- /** Removes the n-th message that satisfies the predicate <code>p</code>.
- */
- def remove(n: Int)(p: (Msg, OutputChannel[Any]) => Boolean): Option[(Msg, OutputChannel[Any])] =
- removeInternal(n)(p) map (x => (x.msg, x.session))
-
- /** Extracts the first message that satisfies the predicate `p`
- * or `'''null'''` if `p` fails for all of them.
- */
- def extractFirst(p: (Msg, OutputChannel[Any]) => Boolean): MQueueElement[Msg] =
- removeInternal(0)(p).orNull
-
- def extractFirst(pf: PartialFunction[Msg, Any]): MQueueElement[Msg] = {
- if (isEmpty) // early return
- return null
-
- // special handling if returning the head
- if (pf.isDefinedAt(first.msg)) {
- val res = first
- first = first.next
- if (res eq last)
- last = null
-
- changeSize(-1)
- res
- }
- else {
- var curr = first.next // init to element #2
- var prev = first
-
- while (curr != null) {
- if (pf.isDefinedAt(curr.msg)) {
- prev.next = curr.next
- if (curr eq last)
- last = prev
-
- changeSize(-1)
- return curr // early return
- }
- else {
- prev = curr
- curr = curr.next
- }
- }
- // not found
- null
- }
- }
-
- private def removeInternal(n: Int)(p: (Msg, OutputChannel[Any]) => Boolean): Option[MQueueElement[Msg]] = {
- var pos = 0
-
- def foundMsg(x: MQueueElement[Msg]) = {
- changeSize(-1)
- Some(x)
- }
- def test(msg: Msg, session: OutputChannel[Any]): Boolean =
- p(msg, session) && (pos == n || { pos += 1 ; false })
-
- if (isEmpty) // early return
- return None
-
- // special handling if returning the head
- if (test(first.msg, first.session)) {
- val res = first
- first = first.next
- if (res eq last)
- last = null
-
- foundMsg(res)
- }
- else {
- var curr = first.next // init to element #2
- var prev = first
-
- while (curr != null) {
- if (test(curr.msg, curr.session)) {
- prev.next = curr.next
- if (curr eq last)
- last = prev
-
- return foundMsg(curr) // early return
- }
- else {
- prev = curr
- curr = curr.next
- }
- }
- // not found
- None
- }
- }
-}
-
-/** Debugging trait.
- */
-private[actors] trait MessageQueueTracer extends MQueue[Any]
-{
- private val queueNumber = MessageQueueTracer.getQueueNumber
-
- override def append(msg: Any, session: OutputChannel[Any]) {
- super.append(msg, session)
- printQueue("APPEND %s" format msg)
- }
- override def get(n: Int)(p: Any => Boolean): Option[Any] = {
- val res = super.get(n)(p)
- printQueue("GET %s" format res)
- res
- }
- override def remove(n: Int)(p: (Any, OutputChannel[Any]) => Boolean): Option[(Any, OutputChannel[Any])] = {
- val res = super.remove(n)(p)
- printQueue("REMOVE %s" format res)
- res
- }
- override def extractFirst(p: (Any, OutputChannel[Any]) => Boolean): MQueueElement[Any] = {
- val res = super.extractFirst(p)
- printQueue("EXTRACT_FIRST %s" format res)
- res
- }
-
- private def printQueue(msg: String) = {
- def firstMsg = if (first eq null) "null" else first.msg
- def lastMsg = if (last eq null) "null" else last.msg
-
- println("[%s size=%d] [%s] first = %s, last = %s".format(this, size, msg, firstMsg, lastMsg))
- }
- override def toString() = "%s:%d".format(label, queueNumber)
-}
-
-private[actors] object MessageQueueTracer {
- // for tracing purposes
- private var queueNumberAssigner = 0
- private def getQueueNumber = synchronized {
- queueNumberAssigner += 1
- queueNumberAssigner
- }
-}
diff --git a/src/actors/scala/actors/OutputChannel.scala b/src/actors/scala/actors/OutputChannel.scala
deleted file mode 100644
index f0f475e123..0000000000
--- a/src/actors/scala/actors/OutputChannel.scala
+++ /dev/null
@@ -1,48 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala.actors
-
-/**
- * A common interface for all channels to which values can be sent.
- *
- * @author Philipp Haller
- *
- * @define actor `OutputChannel`
- */
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-trait OutputChannel[-Msg] {
-
- /**
- * Sends `msg` to this $actor (asynchronous).
- *
- * @param msg the message to send
- */
- def !(msg: Msg): Unit
-
- /**
- * Sends `msg` to this $actor (asynchronous) supplying
- * explicit reply destination.
- *
- * @param msg the message to send
- * @param replyTo the reply destination
- */
- def send(msg: Msg, replyTo: OutputChannel[Any]): Unit
-
- /**
- * Forwards `msg` to this $actor (asynchronous).
- *
- * @param msg the message to forward
- */
- def forward(msg: Msg): Unit
-
- /**
- * Returns the `Actor` that is receiving from this $actor.
- */
- def receiver: InternalActor
-}
diff --git a/src/actors/scala/actors/ReactChannel.scala b/src/actors/scala/actors/ReactChannel.scala
deleted file mode 100644
index 7e34681fb6..0000000000
--- a/src/actors/scala/actors/ReactChannel.scala
+++ /dev/null
@@ -1,121 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-package scala.actors
-
-/**
- * @author Philipp Haller
- */
-private[actors] class ReactChannel[Msg](receiver: InternalReplyReactor) extends InputChannel[Msg] {
-
- private case class SendToReactor(channel: ReactChannel[Msg], msg: Msg)
-
- /**
- * Sends a message to this <code>ReactChannel</code>.
- *
- * @param msg the message to be sent
- */
- def !(msg: Msg) {
- receiver ! SendToReactor(this, msg)
- }
-
- /**
- * Sends a message to this `ReactChannel` (asynchronous) supplying
- * explicit reply destination.
- *
- * @param msg the message to send
- * @param replyTo the reply destination
- */
- def send(msg: Msg, replyTo: OutputChannel[Any]) {
- receiver.send(SendToReactor(this, msg), replyTo)
- }
-
- /**
- * Forwards `msg` to `'''this'''` keeping the last sender as sender
- * instead of `self`.
- */
- def forward(msg: Msg) {
- receiver forward SendToReactor(this, msg)
- }
-
- /**
- * Receives a message from this `ReactChannel`.
- *
- * This method ''never'' returns. Therefore, the rest of the computation
- * has to be contained in the actions of the partial function.
- *
- * @param f a partial function with message patterns and actions
- */
- def react(f: PartialFunction[Msg, Unit]): Nothing = {
- val C = this
- receiver.react {
- case SendToReactor(C, msg) if (f.isDefinedAt(msg.asInstanceOf[Msg])) =>
- f(msg.asInstanceOf[Msg])
- }
- }
-
- /**
- * Receives a message from this `ReactChannel` within a certain time span.
- *
- * This method ''never'' returns. Therefore, the rest of the computation
- * has to be contained in the actions of the partial function.
- *
- * @param msec the time span before timeout
- * @param f a partial function with message patterns and actions
- */
- def reactWithin(msec: Long)(f: PartialFunction[Any, Unit]): Nothing = {
- val C = this
- val recvActor = receiver.asInstanceOf[Actor]
- recvActor.reactWithin(msec) {
- case C ! msg if (f.isDefinedAt(msg.asInstanceOf[Msg])) =>
- f(msg.asInstanceOf[Msg])
- case TIMEOUT => f(TIMEOUT)
- }
- }
-
- /**
- * Receives a message from this `ReactChannel`.
- *
- * @param f a partial function with message patterns and actions
- * @return result of processing the received value
- */
- def receive[R](f: PartialFunction[Msg, R]): R = {
- val C = this
- val recvActor = receiver.asInstanceOf[Actor]
- recvActor.receive {
- case C ! msg if (f.isDefinedAt(msg.asInstanceOf[Msg])) =>
- f(msg.asInstanceOf[Msg])
- }
- }
-
- /**
- * Receives a message from this `ReactChannel` within a certain time span.
- *
- * @param msec the time span before timeout
- * @param f a partial function with message patterns and actions
- * @return result of processing the received value
- */
- def receiveWithin[R](msec: Long)(f: PartialFunction[Any, R]): R = {
- val C = this
- val recvActor = receiver.asInstanceOf[Actor]
- recvActor.receiveWithin(msec) {
- case C ! msg if (f.isDefinedAt(msg.asInstanceOf[Msg])) =>
- f(msg.asInstanceOf[Msg])
- case TIMEOUT => f(TIMEOUT)
- }
- }
-
- /**
- * Receives the next message from this `ReactChannel`.
- */
- def ? : Msg = receive {
- case x => x
- }
-
-}
diff --git a/src/actors/scala/actors/Reactor.scala b/src/actors/scala/actors/Reactor.scala
deleted file mode 100644
index aa985b3a17..0000000000
--- a/src/actors/scala/actors/Reactor.scala
+++ /dev/null
@@ -1,307 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-package scala.actors
-
-import scala.actors.scheduler.{DelegatingScheduler, ExecutorScheduler,
- ForkJoinScheduler, ThreadPoolConfig}
-import java.util.concurrent.{ThreadPoolExecutor, TimeUnit, LinkedBlockingQueue}
-import scala.language.implicitConversions
-
-private[actors] object Reactor {
-
- val scheduler = new DelegatingScheduler {
- def makeNewScheduler: IScheduler = {
- val sched = if (!ThreadPoolConfig.useForkJoin) {
- // default is non-daemon
- val workQueue = new LinkedBlockingQueue[Runnable]
- ExecutorScheduler(
- new ThreadPoolExecutor(ThreadPoolConfig.corePoolSize,
- ThreadPoolConfig.maxPoolSize,
- 60000L,
- TimeUnit.MILLISECONDS,
- workQueue,
- new ThreadPoolExecutor.CallerRunsPolicy))
- } else {
- // default is non-daemon, non-fair
- val s = new ForkJoinScheduler(ThreadPoolConfig.corePoolSize, ThreadPoolConfig.maxPoolSize, false, false)
- s.start()
- s
- }
- Debug.info(this+": starting new "+sched+" ["+sched.getClass+"]")
- sched
- }
- }
-
- val waitingForNone: PartialFunction[Any, Unit] = new PartialFunction[Any, Unit] {
- def isDefinedAt(x: Any) = false
- def apply(x: Any) {}
- }
-}
-
-/**
- * Super trait of all actor traits.
- *
- * @author Philipp Haller
- *
- * @define actor reactor
- */
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-trait Reactor[Msg >: Null] extends OutputChannel[Msg] with Combinators {
-
- /* The $actor's mailbox. */
- private[actors] val mailbox = new MQueue[Msg]("Reactor")
-
- // guarded by this
- private[actors] val sendBuffer = new MQueue[Msg]("SendBuffer")
-
- /* Whenever this $actor executes on some thread, `waitingFor` is
- * guaranteed to be equal to `Reactor.waitingForNone`.
- *
- * In other words, whenever `waitingFor` is not equal to
- * `Reactor.waitingForNone`, this $actor is guaranteed not to execute
- * on some thread.
- *
- * If the $actor waits in a `react`, `waitingFor` holds the
- * message handler that `react` was called with.
- *
- * guarded by this
- */
- private[actors] var waitingFor: PartialFunction[Msg, Any] =
- Reactor.waitingForNone
-
- // guarded by this
- private[actors] var _state: Actor.State.Value = Actor.State.New
-
- /**
- * The $actor's behavior is specified by implementing this method.
- */
- def act(): Unit
-
- /**
- * This partial function is applied to exceptions that propagate out of
- * this $actor's body.
- */
- protected[actors] def exceptionHandler: PartialFunction[Exception, Unit] =
- Map()
-
- protected[actors] def scheduler: IScheduler =
- Reactor.scheduler
-
- protected[actors] def mailboxSize: Int =
- mailbox.size
-
- def send(msg: Msg, replyTo: OutputChannel[Any]) {
- val todo = synchronized {
- if (waitingFor ne Reactor.waitingForNone) {
- val savedWaitingFor = waitingFor
- waitingFor = Reactor.waitingForNone
- startSearch(msg, replyTo, savedWaitingFor)
- } else {
- sendBuffer.append(msg, replyTo)
- () => { /* do nothing */ }
- }
- }
- todo()
- }
-
- private[actors] def startSearch(msg: Msg, replyTo: OutputChannel[Any], handler: PartialFunction[Msg, Any]) =
- () => scheduler execute makeReaction(() => {
- val startMbox = new MQueue[Msg]("Start")
- synchronized { startMbox.append(msg, replyTo) }
- searchMailbox(startMbox, handler, true)
- })
-
- private[actors] final def makeReaction(fun: () => Unit): Runnable =
- makeReaction(fun, null, null)
-
- /* This method is supposed to be overridden. */
- private[actors] def makeReaction(fun: () => Unit, handler: PartialFunction[Msg, Any], msg: Msg): Runnable =
- new ReactorTask(this, fun, handler, msg)
-
- private[actors] def resumeReceiver(item: (Msg, OutputChannel[Any]), handler: PartialFunction[Msg, Any], onSameThread: Boolean) {
- if (onSameThread)
- makeReaction(null, handler, item._1).run()
- else
- scheduleActor(handler, item._1)
-
- /* Here, we throw a SuspendActorControl to avoid
- terminating this actor when the current ReactorTask
- is finished.
-
- The SuspendActorControl skips the termination code
- in ReactorTask.
- */
- throw Actor.suspendException
- }
-
- def !(msg: Msg) {
- send(msg, null)
- }
-
- def forward(msg: Msg) {
- send(msg, null)
- }
-
- def receiver: Actor = this.asInstanceOf[Actor]
-
- // guarded by this
- private[actors] def drainSendBuffer(mbox: MQueue[Msg]) {
- sendBuffer.foreachDequeue(mbox)
- }
-
- private[actors] def searchMailbox(startMbox: MQueue[Msg],
- handler: PartialFunction[Msg, Any],
- resumeOnSameThread: Boolean) {
- var tmpMbox = startMbox
- var done = false
- while (!done) {
- val qel = tmpMbox.extractFirst(handler)
- if (tmpMbox ne mailbox)
- tmpMbox.foreachAppend(mailbox)
- if (null eq qel) {
- synchronized {
- // in mean time new stuff might have arrived
- if (!sendBuffer.isEmpty) {
- tmpMbox = new MQueue[Msg]("Temp")
- drainSendBuffer(tmpMbox)
- // keep going
- } else {
- waitingFor = handler
- /* Here, we throw a SuspendActorControl to avoid
- terminating this actor when the current ReactorTask
- is finished.
-
- The SuspendActorControl skips the termination code
- in ReactorTask.
- */
- throw Actor.suspendException
- }
- }
- } else {
- resumeReceiver((qel.msg, qel.session), handler, resumeOnSameThread)
- done = true
- }
- }
- }
-
- /**
- * Receives a message from this $actor's mailbox.
- *
- * This method never returns. Therefore, the rest of the computation
- * has to be contained in the actions of the partial function.
- *
- * @param handler a partial function with message patterns and actions
- */
- protected def react(handler: PartialFunction[Msg, Unit]): Nothing = {
- synchronized { drainSendBuffer(mailbox) }
- searchMailbox(mailbox, handler, false)
- throw Actor.suspendException
- }
-
- /* This method is guaranteed to be executed from inside
- * an $actor's act method.
- *
- * assume handler != null
- *
- * never throws SuspendActorControl
- */
- private[actors] def scheduleActor(handler: PartialFunction[Msg, Any], msg: Msg) {
- scheduler executeFromActor makeReaction(null, handler, msg)
- }
-
- private[actors] def preAct() = {}
-
- // guarded by this
- private[actors] def dostart() {
- _state = Actor.State.Runnable
- scheduler newActor this
- scheduler execute makeReaction(() => {
- preAct()
- act()
- }, null, null)
- }
-
- /**
- * Starts this $actor. This method is idempotent.
- */
- def start(): Reactor[Msg] = synchronized {
- if (_state == Actor.State.New)
- dostart()
- this
- }
-
- /**
- * Restarts this $actor.
- *
- * @throws java.lang.IllegalStateException if the $actor is not in state `Actor.State.Terminated`
- */
- def restart(): Unit = synchronized {
- if (_state == Actor.State.Terminated)
- dostart()
- else
- throw new IllegalStateException("restart only in state "+Actor.State.Terminated)
- }
-
- /** Returns the execution state of this $actor.
- *
- * @return the execution state
- */
- def getState: Actor.State.Value = synchronized {
- if (waitingFor ne Reactor.waitingForNone)
- Actor.State.Suspended
- else
- _state
- }
-
- implicit def mkBody[A](body: => A) = new InternalActor.Body[A] {
- def andThen[B](other: => B): Unit = Reactor.this.seq(body, other)
- }
-
- /* This closure is used to implement control-flow operations
- * built on top of `seq`. Note that the only invocation of
- * `kill` is supposed to be inside `ReactorTask.run`.
- */
- @volatile
- private[actors] var kill: () => Unit =
- () => { exit() }
-
- private[actors] def seq[a, b](first: => a, next: => b): Unit = {
- val killNext = this.kill
- this.kill = () => {
- this.kill = killNext
-
- // to avoid stack overflow:
- // instead of directly executing `next`,
- // schedule as continuation
- scheduleActor({ case _ => next }, null)
- throw Actor.suspendException
- }
- first
- throw new KillActorControl
- }
-
- protected[actors] def exit(): Nothing = {
- terminated()
- throw Actor.suspendException
- }
-
- private[actors] def internalPostStop() = {}
-
- private[actors] def terminated() {
- synchronized {
- _state = Actor.State.Terminated
- // reset waitingFor, otherwise getState returns Suspended
- waitingFor = Reactor.waitingForNone
- }
- internalPostStop()
- scheduler.terminated(this)
- }
-
-}
diff --git a/src/actors/scala/actors/ReactorCanReply.scala b/src/actors/scala/actors/ReactorCanReply.scala
deleted file mode 100644
index e30efcbed8..0000000000
--- a/src/actors/scala/actors/ReactorCanReply.scala
+++ /dev/null
@@ -1,90 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-package scala.actors
-
-/**
- * Provides message send operations that
- * may result in a response from the receiver.
- *
- * @author Philipp Haller
- */
-private[actors] trait ReactorCanReply extends CanReply[Any, Any] {
- _: InternalReplyReactor =>
-
- type Future[+P] = scala.actors.Future[P]
-
- def !?(msg: Any): Any =
- (this !! msg)()
-
- def !?(msec: Long, msg: Any): Option[Any] = {
- val myself = Actor.rawSelf(this.scheduler)
- val res = new scala.concurrent.SyncVar[Any]
- val out = new OutputChannel[Any] {
- def !(msg: Any) =
- res set msg
- def send(msg: Any, replyTo: OutputChannel[Any]) =
- res set msg
- def forward(msg: Any) =
- res set msg
- def receiver =
- myself.asInstanceOf[Actor]
- }
- this.send(msg, out)
- res.get(msec)
- }
-
- def !!(msg: Any): Future[Any] =
- this !! (msg, { case x => x })
-
- def !![A](msg: Any, handler: PartialFunction[Any, A]): Future[A] = {
- val myself = Actor.rawSelf(this.scheduler)
- val ftch = new ReactChannel[A](myself)
- val res = new scala.concurrent.SyncVar[A]
-
- val out = new OutputChannel[Any] {
- def !(msg: Any) = {
- val msg1 = handler(msg)
- ftch ! msg1
- res set msg1
- }
- def send(msg: Any, replyTo: OutputChannel[Any]) = {
- val msg1 = handler(msg)
- ftch.send(msg1, replyTo)
- res set msg1
- }
- def forward(msg: Any) = {
- val msg1 = handler(msg)
- ftch forward msg1
- res set msg1
- }
- def receiver =
- myself.asInstanceOf[Actor]
- }
-
- this.send(msg, out)
-
- new Future[A] {
- def apply() = {
- if (!isSet)
- fvalue = Some(res.get)
-
- fvalueTyped
- }
- def respond(k: A => Unit): Unit =
- if (isSet) k(fvalueTyped)
- else inputChannel.react {
- case any => fvalue = Some(any); k(fvalueTyped)
- }
- def isSet =
- !fvalue.isEmpty
- def inputChannel = ftch
- }
- }
-}
diff --git a/src/actors/scala/actors/ReactorTask.scala b/src/actors/scala/actors/ReactorTask.scala
deleted file mode 100644
index 1ca061b40d..0000000000
--- a/src/actors/scala/actors/ReactorTask.scala
+++ /dev/null
@@ -1,74 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-package scala.actors
-
-import java.lang.Runnable
-import java.util.concurrent.Callable
-
-import scala.concurrent.forkjoin.RecursiveAction
-
-/**
- * @author Philipp Haller
- */
-private[actors] class ReactorTask[Msg >: Null](var reactor: Reactor[Msg],
- var fun: () => Any,
- var handler: PartialFunction[Msg, Any],
- var msg: Msg)
- extends RecursiveAction with Callable[Unit] with Runnable {
-
- def run() {
- try {
- beginExecution()
- try {
- if (fun eq null)
- handler(msg)
- else
- fun()
- } catch {
- case _: KillActorControl =>
- // do nothing
-
- case e: Exception if reactor.exceptionHandler.isDefinedAt(e) =>
- reactor.exceptionHandler(e)
- }
- reactor.kill()
- }
- catch {
- case _: SuspendActorControl =>
- // do nothing (continuation is already saved)
-
- case e: Throwable =>
- terminateExecution(e)
- reactor.terminated()
- if (!e.isInstanceOf[Exception])
- throw e
- } finally {
- suspendExecution()
- this.reactor = null
- this.fun = null
- this.handler = null
- this.msg = null
- }
- }
-
- def call() = run()
-
- def compute() = run()
-
- protected def beginExecution() {}
-
- protected def suspendExecution() {}
-
- protected def terminateExecution(e: Throwable) {
- Console.err.println(reactor+": caught "+e)
- e.printStackTrace()
- }
-
-}
diff --git a/src/actors/scala/actors/ReplyReactor.scala b/src/actors/scala/actors/ReplyReactor.scala
deleted file mode 100644
index 01e6da000f..0000000000
--- a/src/actors/scala/actors/ReplyReactor.scala
+++ /dev/null
@@ -1,13 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-package scala.actors
-
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-trait ReplyReactor extends InternalReplyReactor {
- protected[actors] def sender: OutputChannel[Any] = super.internalSender
-}
diff --git a/src/actors/scala/actors/ReplyReactorTask.scala b/src/actors/scala/actors/ReplyReactorTask.scala
deleted file mode 100644
index ea9070fab7..0000000000
--- a/src/actors/scala/actors/ReplyReactorTask.scala
+++ /dev/null
@@ -1,40 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.actors
-
-/**
- * @author Philipp Haller
- * @note This class inherits a public var called 'reactor' from ReactorTask,
- * and also defines a constructor parameter which shadows it (which makes any
- * changes to the underlying var invisible.) I can't figure out what's supposed
- * to happen, so I renamed the constructor parameter to at least be less confusing.
- */
-private[actors] class ReplyReactorTask(replyReactor: InternalReplyReactor,
- fun: () => Unit,
- handler: PartialFunction[Any, Any],
- msg: Any)
- extends ReactorTask(replyReactor, fun, handler, msg) {
-
- var saved: InternalReplyReactor = _
-
- protected override def beginExecution() {
- saved = Actor.tl.get
- // !!! If this is supposed to be setting the current contents of the
- // inherited mutable var rather than always the value given in the constructor,
- // then it should be changed to "set reactor".
- Actor.tl set replyReactor
- }
-
- protected override def suspendExecution() {
- Actor.tl set saved
- }
-
-}
diff --git a/src/actors/scala/actors/Scheduler.scala b/src/actors/scala/actors/Scheduler.scala
deleted file mode 100644
index 67c8e5cd10..0000000000
--- a/src/actors/scala/actors/Scheduler.scala
+++ /dev/null
@@ -1,40 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-package scala.actors
-
-import scheduler.{DelegatingScheduler, ForkJoinScheduler, ResizableThreadPoolScheduler, ThreadPoolConfig}
-
-/**
- * Used by [[scala.actors.Actor]] instances to
- * execute tasks of an actor execution.
- *
- * @author Philipp Haller
- */
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-object Scheduler extends DelegatingScheduler {
-
- Debug.info("initializing "+this+"...")
-
- def makeNewScheduler: IScheduler = {
- val sched = if (!ThreadPoolConfig.useForkJoin) {
- // default is non-daemon
- val s = new ResizableThreadPoolScheduler(false)
- s.start()
- s
- } else {
- // default is non-daemon, fair
- val s = new ForkJoinScheduler
- s.start()
- s
- }
- Debug.info(this+": starting new "+sched+" ["+sched.getClass+"]")
- sched
- }
-}
diff --git a/src/actors/scala/actors/SchedulerAdapter.scala b/src/actors/scala/actors/SchedulerAdapter.scala
deleted file mode 100644
index b8e66dd6cc..0000000000
--- a/src/actors/scala/actors/SchedulerAdapter.scala
+++ /dev/null
@@ -1,68 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-package scala.actors
-
-/** Adapts
- * the behavior of the standard [[scala.actors.Scheduler]] object.
- *
- * Providing an implementation for the
- * <code>execute(f: => Unit)</code> method is sufficient to
- * obtain a concrete <code>IScheduler</code> implementation.
- *
- * @author Philipp Haller
- */
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-trait SchedulerAdapter extends IScheduler {
-
- /** Submits a <code>Runnable</code> for execution.
- *
- * @param task the task to be executed
- */
- def execute(task: Runnable): Unit =
- execute { task.run() }
-
- /** Shuts down the scheduler.
- */
- def shutdown(): Unit =
- Scheduler.shutdown()
-
- /** When the scheduler is active, it can execute tasks.
- */
- def isActive: Boolean =
- Scheduler.isActive
-
- /** Registers a newly created actor with this scheduler.
- *
- * @param a the actor to be registered
- */
- def newActor(a: TrackedReactor) =
- Scheduler.newActor(a)
-
- /** Unregisters an actor from this scheduler, because it
- * has terminated.
- *
- * @param a the actor to be unregistered
- */
- def terminated(a: TrackedReactor) =
- Scheduler.terminated(a)
-
- /** Registers a closure to be executed when the specified
- * actor terminates.
- *
- * @param a the actor
- * @param f the closure to be registered
- */
- def onTerminate(a: TrackedReactor)(f: => Unit) =
- Scheduler.onTerminate(a)(f)
-
- def managedBlock(blocker: scala.concurrent.ManagedBlocker) {
- blocker.block()
- }
-}
diff --git a/src/actors/scala/actors/UncaughtException.scala b/src/actors/scala/actors/UncaughtException.scala
deleted file mode 100644
index 02b916a3b5..0000000000
--- a/src/actors/scala/actors/UncaughtException.scala
+++ /dev/null
@@ -1,34 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala.actors
-
-/**
- * The exit reason when an actor fails to catch an exception.
- *
- * @param actor the actor that threw the exception
- * @param message the message the actor was processing, or None if no message (e.g. on initial startup)
- * @param sender the sender of the most recent message
- * @param thread the thread on which the actor was running
- * @param cause the uncaught exception
- *
- * @author Philipp Haller
- * @author Erik Engbrecht
- */
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-case class UncaughtException(actor: InternalActor,
- message: Option[Any],
- sender: Option[OutputChannel[Any]],
- thread: Thread,
- cause: Throwable)
-extends Exception(cause) {
-
- override def toString() =
- "UncaughtException("+actor+","+message+","+sender+","+cause+")"
-
-}
diff --git a/src/actors/scala/actors/package.scala b/src/actors/scala/actors/package.scala
deleted file mode 100644
index ae960860cf..0000000000
--- a/src/actors/scala/actors/package.scala
+++ /dev/null
@@ -1,23 +0,0 @@
-package scala
-
-/**
- * A library that provides both asynchronous and synchronous messaging to allow
- * for concurrent programming without explicit synchronization.
- *
- * == Guide ==
- *
- * A detailed guide for the actors library is available
- * [[http://docs.scala-lang.org/overviews/core/actors.html]].
- *
- * == Getting Started ==
- *
- * A starting point for using the actors library would be [[scala.actors.Reactor]],
- * [[scala.actors.ReplyReactor]], or [[scala.actors.Actor]] or their companion objects.
- *
- * @note As of release 2.10.1, replaced by <code>akka.actor</code> package. For migration of existing actors refer to the Actors Migration Guide.
- */
-package object actors {
-
- // type of Reactors tracked by termination detector
- private[actors] type TrackedReactor = Reactor[A] forSome { type A >: Null }
-}
diff --git a/src/actors/scala/actors/remote/FreshNameCreator.scala b/src/actors/scala/actors/remote/FreshNameCreator.scala
deleted file mode 100644
index f7cf29387e..0000000000
--- a/src/actors/scala/actors/remote/FreshNameCreator.scala
+++ /dev/null
@@ -1,36 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-package scala.actors
-package remote
-
-object FreshNameCreator {
-
- protected var counter = 0
- protected val counters = new scala.collection.mutable.HashMap[String, Int]
-
- /**
- * Create a fresh name with the given prefix. It is guaranteed
- * that the returned name has never been returned by a previous
- * call to this function (provided the prefix does not end in a digit).
- */
- def newName(prefix: String): Symbol = {
- val count = counters.get(prefix) match {
- case Some(last) => last + 1
- case None => 0
- }
- counters.update(prefix, count)
- Symbol(prefix + count)
- }
-
- def newName(): Symbol = {
- counter += 1
- Symbol("$" + counter + "$")
- }
-}
diff --git a/src/actors/scala/actors/remote/JavaSerializer.scala b/src/actors/scala/actors/remote/JavaSerializer.scala
deleted file mode 100644
index 7549bbf429..0000000000
--- a/src/actors/scala/actors/remote/JavaSerializer.scala
+++ /dev/null
@@ -1,63 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-package scala.actors
-package remote
-
-import java.io.{ByteArrayInputStream, ByteArrayOutputStream,
- ObjectInputStream, ObjectOutputStream, InputStream,
- ObjectStreamClass}
-
-/**
- * @author Guy Oliver
- */
-private[remote] class CustomObjectInputStream(in: InputStream, cl: ClassLoader)
-extends ObjectInputStream(in) {
- override def resolveClass(cd: ObjectStreamClass): Class[_] =
- try {
- cl.loadClass(cd.getName())
- } catch {
- case cnf: ClassNotFoundException =>
- super.resolveClass(cd)
- }
- override def resolveProxyClass(interfaces: Array[String]): Class[_] =
- try {
- val ifaces = interfaces map { iface => cl.loadClass(iface) }
- java.lang.reflect.Proxy.getProxyClass(cl, ifaces: _*)
- } catch {
- case e: ClassNotFoundException =>
- super.resolveProxyClass(interfaces)
- }
-}
-
-/**
- * @author Philipp Haller
- */
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-class JavaSerializer(serv: Service, cl: ClassLoader) extends Serializer(serv) {
- def serialize(o: AnyRef): Array[Byte] = {
- val bos = new ByteArrayOutputStream()
- val out = new ObjectOutputStream(bos)
- out.writeObject(o)
- out.flush()
- bos.toByteArray()
- }
-
- def deserialize(bytes: Array[Byte]): AnyRef = {
- val bis = new ByteArrayInputStream(bytes)
-
- // use custom stream only if cl != null
- val in = if (cl != null)
- new CustomObjectInputStream(bis, cl)
- else
- new ObjectInputStream(bis)
-
- in.readObject()
- }
-}
diff --git a/src/actors/scala/actors/remote/NetKernel.scala b/src/actors/scala/actors/remote/NetKernel.scala
deleted file mode 100644
index 57d7af6d26..0000000000
--- a/src/actors/scala/actors/remote/NetKernel.scala
+++ /dev/null
@@ -1,147 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-package scala.actors
-package remote
-
-import scala.collection.mutable
-
-case class NamedSend(senderLoc: Locator, receiverLoc: Locator, data: Array[Byte], session: Symbol)
-
-case class RemoteApply0(senderLoc: Locator, receiverLoc: Locator, rfun: Function2[AbstractActor, Proxy, Unit])
-case class LocalApply0(rfun: Function2[AbstractActor, Proxy, Unit], a: AbstractActor)
-
-case class SendTo(a: OutputChannel[Any], msg: Any, session: Symbol)
-case object Terminate
-
-case class Locator(node: Node, name: Symbol)
-
-/**
- * @version 0.9.17
- * @author Philipp Haller
- */
-private[remote] class NetKernel(service: Service) {
-
- def sendToNode(node: Node, msg: AnyRef) = {
- val bytes = service.serializer.serialize(msg)
- service.send(node, bytes)
- }
-
- def namedSend(senderLoc: Locator, receiverLoc: Locator,
- msg: AnyRef, session: Symbol) {
- val bytes = service.serializer.serialize(msg)
- sendToNode(receiverLoc.node, NamedSend(senderLoc, receiverLoc, bytes, session))
- }
-
- private val actors = new mutable.HashMap[Symbol, OutputChannel[Any]]
- private val names = new mutable.HashMap[OutputChannel[Any], Symbol]
-
- def register(name: Symbol, a: OutputChannel[Any]): Unit = synchronized {
- actors(name) = a
- names(a) = name
- }
-
- def getOrCreateName(from: OutputChannel[Any]) = names.get(from) match {
- case None =>
- val freshName = FreshNameCreator.newName("remotesender")
- register(freshName, from)
- freshName
- case Some(name) =>
- name
- }
-
- def send(node: Node, name: Symbol, msg: AnyRef): Unit =
- send(node, name, msg, 'nosession)
-
- def send(node: Node, name: Symbol, msg: AnyRef, session: Symbol) {
- val senderLoc = Locator(service.node, getOrCreateName(Actor.self(Scheduler)))
- val receiverLoc = Locator(node, name)
- namedSend(senderLoc, receiverLoc, msg, session)
- }
-
- def forward(from: OutputChannel[Any], node: Node, name: Symbol, msg: AnyRef, session: Symbol) {
- val senderLoc = Locator(service.node, getOrCreateName(from))
- val receiverLoc = Locator(node, name)
- namedSend(senderLoc, receiverLoc, msg, session)
- }
-
- def remoteApply(node: Node, name: Symbol, from: OutputChannel[Any], rfun: Function2[AbstractActor, Proxy, Unit]) {
- val senderLoc = Locator(service.node, getOrCreateName(from))
- val receiverLoc = Locator(node, name)
- sendToNode(receiverLoc.node, RemoteApply0(senderLoc, receiverLoc, rfun))
- }
-
- def createProxy(node: Node, sym: Symbol): Proxy = {
- val p = new Proxy(node, sym, this)
- proxies((node, sym)) = p
- p
- }
-
- val proxies = new mutable.HashMap[(Node, Symbol), Proxy]
-
- def getOrCreateProxy(senderNode: Node, senderName: Symbol): Proxy =
- proxies.synchronized {
- proxies.get((senderNode, senderName)) match {
- case Some(senderProxy) => senderProxy
- case None => createProxy(senderNode, senderName)
- }
- }
-
- /* Register proxy if no other proxy has been registered.
- */
- def registerProxy(senderNode: Node, senderName: Symbol, p: Proxy): Unit =
- proxies.synchronized {
- proxies.get((senderNode, senderName)) match {
- case Some(senderProxy) => // do nothing
- case None => proxies((senderNode, senderName)) = p
- }
- }
-
- def processMsg(senderNode: Node, msg: AnyRef): Unit = synchronized {
- msg match {
- case cmd@RemoteApply0(senderLoc, receiverLoc, rfun) =>
- Debug.info(this+": processing "+cmd)
- actors.get(receiverLoc.name) match {
- case Some(a) =>
- val senderProxy = getOrCreateProxy(senderLoc.node, senderLoc.name)
- senderProxy.send(LocalApply0(rfun, a.asInstanceOf[AbstractActor]), null)
-
- case None =>
- // message is lost
- Debug.info(this+": lost message")
- }
-
- case cmd@NamedSend(senderLoc, receiverLoc, data, session) =>
- Debug.info(this+": processing "+cmd)
- actors.get(receiverLoc.name) match {
- case Some(a) =>
- try {
- val msg = service.serializer.deserialize(data)
- val senderProxy = getOrCreateProxy(senderLoc.node, senderLoc.name)
- senderProxy.send(SendTo(a, msg, session), null)
- } catch {
- case e: Exception =>
- Debug.error(this+": caught "+e)
- }
-
- case None =>
- // message is lost
- Debug.info(this+": lost message")
- }
- }
- }
-
- def terminate() {
- // tell all proxies to terminate
- proxies.values foreach { _.send(Terminate, null) }
-
- // tell service to terminate
- service.terminate()
- }
-}
diff --git a/src/actors/scala/actors/remote/Proxy.scala b/src/actors/scala/actors/remote/Proxy.scala
deleted file mode 100644
index 2cb03544f2..0000000000
--- a/src/actors/scala/actors/remote/Proxy.scala
+++ /dev/null
@@ -1,190 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-package scala.actors
-package remote
-
-import scala.collection.mutable
-
-/**
- * @author Philipp Haller
- */
-private[remote] class Proxy(node: Node, name: Symbol, @transient var kernel: NetKernel) extends AbstractActor with Serializable {
- import java.io.{IOException, ObjectOutputStream, ObjectInputStream}
-
- type Future[+P] = scala.actors.Future[P]
-
- @transient
- private[remote] var del: Actor = null
- startDelegate()
-
- @throws(classOf[IOException])
- private def writeObject(out: ObjectOutputStream) {
- out.defaultWriteObject()
- }
-
- @throws(classOf[ClassNotFoundException]) @throws(classOf[IOException])
- private def readObject(in: ObjectInputStream) {
- in.defaultReadObject()
- setupKernel()
- startDelegate()
- }
-
- private def startDelegate() {
- del = new DelegateActor(this, node, name, kernel)
- del.start()
- }
-
- private def setupKernel() {
- kernel = RemoteActor.someNetKernel
- kernel.registerProxy(node, name, this)
- }
-
- def !(msg: Any): Unit =
- del ! msg
-
- def send(msg: Any, replyCh: OutputChannel[Any]): Unit =
- del.send(msg, replyCh)
-
- def forward(msg: Any): Unit =
- del.forward(msg)
-
- def receiver: Actor =
- del
-
- def !?(msg: Any): Any =
- del !? msg
-
- def !?(msec: Long, msg: Any): Option[Any] =
- del !? (msec, msg)
-
- def !!(msg: Any): Future[Any] =
- del !! msg
-
- def !![A](msg: Any, f: PartialFunction[Any, A]): Future[A] =
- del !! (msg, f)
-
- def linkTo(to: AbstractActor): Unit =
- del ! Apply0(new LinkToFun)
-
- def unlinkFrom(from: AbstractActor): Unit =
- del ! Apply0(new UnlinkFromFun)
-
- def exit(from: AbstractActor, reason: AnyRef): Unit =
- del ! Apply0(new ExitFun(reason))
-
- override def toString() =
- name+"@"+node
-}
-
-// Proxy is private[remote], but these classes are public and use it in a public
-// method signature. That makes the only method they have non-overridable.
-// So I made them final, which seems appropriate anyway.
-
-final class LinkToFun extends Function2[AbstractActor, Proxy, Unit] with Serializable {
- def apply(target: AbstractActor, creator: Proxy) {
- target.linkTo(creator)
- }
- override def toString =
- "<LinkToFun>"
-}
-
-final class UnlinkFromFun extends Function2[AbstractActor, Proxy, Unit] with Serializable {
- def apply(target: AbstractActor, creator: Proxy) {
- target.unlinkFrom(creator)
- }
- override def toString =
- "<UnlinkFromFun>"
-}
-
-final class ExitFun(reason: AnyRef) extends Function2[AbstractActor, Proxy, Unit] with Serializable {
- def apply(target: AbstractActor, creator: Proxy) {
- target.exit(creator, reason)
- }
- override def toString =
- "<ExitFun>("+reason.toString+")"
-}
-
-private[remote] case class Apply0(rfun: Function2[AbstractActor, Proxy, Unit])
-
-/**
- * @author Philipp Haller
- */
-private[remote] class DelegateActor(creator: Proxy, node: Node, name: Symbol, kernel: NetKernel) extends Actor {
- var channelMap = new mutable.HashMap[Symbol, OutputChannel[Any]]
- var sessionMap = new mutable.HashMap[OutputChannel[_], Symbol]
-
- def act() {
- Actor.loop {
- react {
- case cmd@Apply0(rfun) =>
- kernel.remoteApply(node, name, sender, rfun)
-
- case cmd@LocalApply0(rfun, target) =>
- rfun(target, creator)
-
- // Request from remote proxy.
- // `this` is local proxy.
- case cmd@SendTo(out, msg, session) =>
- if (session.name == "nosession") {
- // local send
- out.send(msg, this)
- } else {
- // is this an active session?
- channelMap.get(session) match {
- case None =>
- // create a new reply channel...
- val replyCh = new Channel[Any](this)
- // ...that maps to session
- sessionMap(replyCh) = session
- // local send
- out.send(msg, replyCh)
-
- // finishes request-reply cycle
- case Some(replyCh) =>
- channelMap -= session
- replyCh ! msg
- }
- }
-
- case cmd@Terminate =>
- exit()
-
- // local proxy receives response to
- // reply channel
- case ch ! resp =>
- // lookup session ID
- sessionMap.get(ch) match {
- case Some(sid) =>
- sessionMap -= ch
- val msg = resp.asInstanceOf[AnyRef]
- // send back response
- kernel.forward(sender, node, name, msg, sid)
-
- case None =>
- Debug.info(this+": cannot find session for "+ch)
- }
-
- // remote proxy receives request
- case msg: AnyRef =>
- // find out whether it's a synchronous send
- if (sender.getClass.toString.contains("Channel")) {
- // create fresh session ID...
- val fresh = FreshNameCreator.newName(node+"@"+name)
- // ...that maps to reply channel
- channelMap(fresh) = sender
- kernel.forward(sender, node, name, msg, fresh)
- } else {
- kernel.forward(sender, node, name, msg, 'nosession)
- }
- }
- }
- }
-
-}
diff --git a/src/actors/scala/actors/remote/RemoteActor.scala b/src/actors/scala/actors/remote/RemoteActor.scala
deleted file mode 100644
index 2daf9ceb43..0000000000
--- a/src/actors/scala/actors/remote/RemoteActor.scala
+++ /dev/null
@@ -1,132 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.actors
-package remote
-
-
-/**
- * This object provides methods for creating, registering, and
- * selecting remotely accessible actors.
- *
- * A remote actor is typically created like this:
- * {{{
- * actor {
- * alive(9010)
- * register('myName, self)
- *
- * // behavior
- * }
- * }}}
- * It can be accessed by an actor running on a (possibly)
- * different node by selecting it in the following way:
- * {{{
- * actor {
- * // ...
- * val c = select(Node("127.0.0.1", 9010), 'myName)
- * c ! msg
- * // ...
- * }
- * }}}
- *
- * @author Philipp Haller
- */
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-object RemoteActor {
-
- private val kernels = new scala.collection.mutable.HashMap[InternalActor, NetKernel]
-
- /* If set to <code>null</code> (default), the default class loader
- * of <code>java.io.ObjectInputStream</code> is used for deserializing
- * objects sent as messages.
- */
- private var cl: ClassLoader = null
-
- def classLoader: ClassLoader = cl
- def classLoader_=(x: ClassLoader) { cl = x }
-
- /**
- * Makes <code>self</code> remotely accessible on TCP port
- * <code>port</code>.
- */
- def alive(port: Int): Unit = synchronized {
- createNetKernelOnPort(port)
- }
-
- private def createNetKernelOnPort(port: Int): NetKernel = {
- val serv = TcpService(port, cl)
- val kern = serv.kernel
- val s = Actor.self(Scheduler)
- kernels(s) = kern
-
- s.onTerminate {
- Debug.info("alive actor "+s+" terminated")
- // remove mapping for `s`
- kernels -= s
- // terminate `kern` when it does
- // not appear as value any more
- if (!kernels.valuesIterator.contains(kern)) {
- Debug.info("terminating "+kern)
- // terminate NetKernel
- kern.terminate()
- }
- }
-
- kern
- }
-
- /**
- * Registers <code>a</code> under <code>name</code> on this
- * node.
- */
- def register(name: Symbol, a: Actor): Unit = synchronized {
- val kernel = kernels.get(Actor.self(Scheduler)) match {
- case None =>
- val serv = TcpService(TcpService.generatePort, cl)
- kernels(Actor.self(Scheduler)) = serv.kernel
- serv.kernel
- case Some(k) =>
- k
- }
- kernel.register(name, a)
- }
-
- private def selfKernel = kernels.get(Actor.self(Scheduler)) match {
- case None =>
- // establish remotely accessible
- // return path (sender)
- createNetKernelOnPort(TcpService.generatePort)
- case Some(k) =>
- k
- }
-
- /**
- * Returns (a proxy for) the actor registered under
- * <code>name</code> on <code>node</code>.
- */
- def select(node: Node, sym: Symbol): AbstractActor = synchronized {
- selfKernel.getOrCreateProxy(node, sym)
- }
-
- private[remote] def someNetKernel: NetKernel =
- kernels.valuesIterator.next
-}
-
-
-/**
- * This class represents a machine node on a TCP network.
- *
- * @param address the host name, or <code>null</code> for the loopback address.
- * @param port the port number.
- *
- * @author Philipp Haller
- */
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-case class Node(address: String, port: Int)
diff --git a/src/actors/scala/actors/remote/Serializer.scala b/src/actors/scala/actors/remote/Serializer.scala
deleted file mode 100644
index 7be4aa6583..0000000000
--- a/src/actors/scala/actors/remote/Serializer.scala
+++ /dev/null
@@ -1,58 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.actors
-package remote
-
-
-import java.lang.ClassNotFoundException
-
-import java.io.{DataInputStream, DataOutputStream, EOFException, IOException}
-
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-abstract class Serializer(val service: Service) {
- def serialize(o: AnyRef): Array[Byte]
- def deserialize(a: Array[Byte]): AnyRef
-
- @throws(classOf[IOException])
- private def readBytes(inputStream: DataInputStream): Array[Byte] = {
- try {
- val length = inputStream.readInt()
- val bytes = new Array[Byte](length)
- inputStream.readFully(bytes, 0, length)
- bytes
- }
- catch {
- case npe: NullPointerException =>
- throw new EOFException("Connection closed.")
- }
- }
-
- @throws(classOf[IOException]) @throws(classOf[ClassNotFoundException])
- def readObject(inputStream: DataInputStream): AnyRef = {
- val bytes = readBytes(inputStream)
- deserialize(bytes)
- }
-
- @throws(classOf[IOException])
- private def writeBytes(outputStream: DataOutputStream, bytes: Array[Byte]) {
- val length = bytes.length;
- // original length
- outputStream.writeInt(length)
- outputStream.write(bytes, 0, length)
- outputStream.flush()
- }
-
- @throws(classOf[IOException])
- def writeObject(outputStream: DataOutputStream, obj: AnyRef) {
- val bytes = serialize(obj)
- writeBytes(outputStream, bytes)
- }
-}
diff --git a/src/actors/scala/actors/remote/Service.scala b/src/actors/scala/actors/remote/Service.scala
deleted file mode 100644
index d102df1970..0000000000
--- a/src/actors/scala/actors/remote/Service.scala
+++ /dev/null
@@ -1,24 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-package scala.actors
-package remote
-
-/**
- * @version 0.9.10
- * @author Philipp Haller
- */
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-trait Service {
- val kernel = new NetKernel(this)
- val serializer: Serializer
- def node: Node
- def send(node: Node, data: Array[Byte]): Unit
- def terminate(): Unit
-}
diff --git a/src/actors/scala/actors/remote/TcpService.scala b/src/actors/scala/actors/remote/TcpService.scala
deleted file mode 100644
index 69e5c46c52..0000000000
--- a/src/actors/scala/actors/remote/TcpService.scala
+++ /dev/null
@@ -1,292 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.actors
-package remote
-
-
-import java.io.{DataInputStream, DataOutputStream, IOException}
-import java.lang.{Thread, SecurityException}
-import java.net.{InetAddress, InetSocketAddress, ServerSocket, Socket, SocketTimeoutException, UnknownHostException}
-
-import scala.collection.mutable
-import scala.util.Random
-
-/* Object TcpService.
- *
- * @version 0.9.9
- * @author Philipp Haller
- */
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-object TcpService {
- private val random = new Random
- private val ports = new mutable.HashMap[Int, TcpService]
-
- def apply(port: Int, cl: ClassLoader): TcpService =
- ports.get(port) match {
- case Some(service) =>
- service
- case None =>
- val service = new TcpService(port, cl)
- ports(port) = service
- service.start()
- Debug.info("created service at "+service.node)
- service
- }
-
- def generatePort: Int = {
- var portnum = 0
- try {
- portnum = 8000 + random.nextInt(500)
- val socket = new ServerSocket(portnum)
- socket.close()
- }
- catch {
- case ioe: IOException =>
- // this happens when trying to open a socket twice
- // at the same port
- // try again
- generatePort
- case se: SecurityException =>
- // do nothing
- }
- portnum
- }
-
- private val connectTimeoutMillis = {
- val propName = "scala.actors.tcpSocket.connectTimeoutMillis"
- val defaultTimeoutMillis = 0
- sys.props get propName flatMap {
- timeout =>
- try {
- val to = timeout.toInt
- Debug.info(s"Using socket timeout $to")
- Some(to)
- } catch {
- case e: NumberFormatException =>
- Debug.warning(s"""Could not parse $propName = "$timeout" as an Int""")
- None
- }
- } getOrElse defaultTimeoutMillis
- }
-
- var BufSize: Int = 65536
-}
-
-/* Class TcpService.
- *
- * @version 0.9.10
- * @author Philipp Haller
- */
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-class TcpService(port: Int, cl: ClassLoader) extends Thread with Service {
- val serializer: JavaSerializer = new JavaSerializer(this, cl)
-
- private val internalNode = new Node(InetAddress.getLocalHost().getHostAddress(), port)
- def node: Node = internalNode
-
- private val pendingSends = new mutable.HashMap[Node, List[Array[Byte]]]
-
- /**
- * Sends a byte array to another node on the network.
- * If the node is not yet up, up to `TcpService.BufSize`
- * messages are buffered.
- */
- def send(node: Node, data: Array[Byte]): Unit = synchronized {
-
- def bufferMsg(t: Throwable) {
- // buffer message, so that it can be re-sent
- // when remote net kernel comes up
- (pendingSends.get(node): @unchecked) match {
- case None =>
- pendingSends(node) = List(data)
- case Some(msgs) if msgs.length < TcpService.BufSize =>
- pendingSends(node) = data :: msgs
- }
- }
-
- // retrieve worker thread (if any) that already has connection
- getConnection(node) match {
- case None =>
- // we are not connected, yet
- try {
- val newWorker = connect(node)
-
- // any pending sends?
- pendingSends.get(node) match {
- case None =>
- // do nothing
- case Some(msgs) =>
- msgs.reverse foreach {newWorker transmit _}
- pendingSends -= node
- }
-
- newWorker transmit data
- } catch {
- case uhe: UnknownHostException =>
- bufferMsg(uhe)
- case ioe: IOException =>
- bufferMsg(ioe)
- case se: SecurityException =>
- // do nothing
- }
- case Some(worker) =>
- worker transmit data
- }
- }
-
- def terminate() {
- shouldTerminate = true
- try {
- new Socket(internalNode.address, internalNode.port)
- } catch {
- case ce: java.net.ConnectException =>
- Debug.info(this+": caught "+ce)
- }
- }
-
- private var shouldTerminate = false
-
- override def run() {
- try {
- val socket = new ServerSocket(port)
- while (!shouldTerminate) {
- Debug.info(this+": waiting for new connection on port "+port+"...")
- val nextClient = socket.accept()
- if (!shouldTerminate) {
- val worker = new TcpServiceWorker(this, nextClient)
- Debug.info("Started new "+worker)
- worker.readNode
- worker.start()
- } else
- nextClient.close()
- }
- } catch {
- case e: Exception =>
- Debug.info(this+": caught "+e)
- } finally {
- Debug.info(this+": shutting down...")
- connections foreach { case (_, worker) => worker.halt }
- }
- }
-
- // connection management
-
- private val connections =
- new mutable.HashMap[Node, TcpServiceWorker]
-
- private[actors] def addConnection(node: Node, worker: TcpServiceWorker) = synchronized {
- connections(node) = worker
- }
-
- def getConnection(n: Node) = synchronized {
- connections.get(n)
- }
-
- def isConnected(n: Node): Boolean = synchronized {
- !connections.get(n).isEmpty
- }
-
- def connect(n: Node): TcpServiceWorker = synchronized {
- val socket = new Socket()
- val start = System.nanoTime
- try {
- socket.connect(new InetSocketAddress(n.address, n.port), TcpService.connectTimeoutMillis)
- } catch {
- case e: SocketTimeoutException =>
- Debug.warning(f"Timed out connecting to $n after ${(System.nanoTime - start) / math.pow(10, 9)}%.3f seconds")
- throw e
- }
- val worker = new TcpServiceWorker(this, socket)
- worker.sendNode(n)
- worker.start()
- addConnection(n, worker)
- worker
- }
-
- def disconnectNode(n: Node) = synchronized {
- connections.get(n) match {
- case None =>
- // do nothing
- case Some(worker) =>
- connections -= n
- worker.halt
- }
- }
-
- def isReachable(node: Node): Boolean =
- if (isConnected(node)) true
- else try {
- connect(node)
- return true
- } catch {
- case uhe: UnknownHostException => false
- case ioe: IOException => false
- case se: SecurityException => false
- }
-
- def nodeDown(mnode: Node): Unit = synchronized {
- connections -= mnode
- }
-}
-
-
-private[actors] class TcpServiceWorker(parent: TcpService, so: Socket) extends Thread {
- val datain = new DataInputStream(so.getInputStream)
- val dataout = new DataOutputStream(so.getOutputStream)
-
- var connectedNode: Node = _
-
- def sendNode(n: Node) {
- connectedNode = n
- parent.serializer.writeObject(dataout, parent.node)
- }
-
- def readNode() {
- val node = parent.serializer.readObject(datain)
- node match {
- case n: Node =>
- connectedNode = n
- parent.addConnection(n, this)
- }
- }
-
- def transmit(data: Array[Byte]): Unit = synchronized {
- Debug.info(this+": transmitting data...")
- dataout.writeInt(data.length)
- dataout.write(data)
- dataout.flush()
- }
-
- var running = true
-
- def halt() = synchronized {
- so.close()
- running = false
- }
-
- override def run() {
- try {
- while (running) {
- val msg = parent.serializer.readObject(datain);
- parent.kernel.processMsg(connectedNode, msg)
- }
- }
- catch {
- case ioe: IOException =>
- Debug.info(this+": caught "+ioe)
- parent nodeDown connectedNode
- case e: Exception =>
- Debug.info(this+": caught "+e)
- parent nodeDown connectedNode
- }
- Debug.info(this+": service terminated at "+parent.node)
- }
-}
diff --git a/src/actors/scala/actors/scheduler/ActorGC.scala b/src/actors/scala/actors/scheduler/ActorGC.scala
deleted file mode 100644
index a27799d132..0000000000
--- a/src/actors/scala/actors/scheduler/ActorGC.scala
+++ /dev/null
@@ -1,101 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-package scala.actors
-package scheduler
-
-import java.lang.ref.{Reference, WeakReference, ReferenceQueue}
-import scala.collection.mutable
-
-/**
- * ActorGC keeps track of the number of live actors being managed by a
- * a scheduler so that it can shutdown when all of the actors it manages have
- * either been explicitly terminated or garbage collected.
- *
- * When an actor is started, it is registered with the ActorGC via the
- * `newActor` method, and when an actor is knowingly terminated
- * (e.g. act method finishes, exit explicitly called, an exception is thrown),
- * the ActorGC is informed via the `terminated` method.
- */
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-trait ActorGC extends TerminationMonitor {
- self: IScheduler =>
-
- /** Actors are added to refQ in newActor. */
- private val refQ = new ReferenceQueue[TrackedReactor]
-
- /**
- * This is a set of references to all the actors registered with
- * this ActorGC. It is maintained so that the WeakReferences will
- * not be GC'd before the actors to which they point.
- */
- private val refSet = new mutable.HashSet[Reference[t] forSome { type t <: TrackedReactor }]
-
- /** newActor is invoked whenever a new actor is started. */
- override def newActor(a: TrackedReactor) = synchronized {
- // registers a reference to the actor with the ReferenceQueue
- val wr = new WeakReference[TrackedReactor](a, refQ)
- refSet += wr
- activeActors += 1
- }
-
- /** Checks for actors that have become garbage. */
- protected override def gc() = synchronized {
- // check for unreachable actors
- def drainRefQ() {
- val wr = refQ.poll
- if (wr != null) {
- activeActors -= 1
- refSet -= wr
- // continue draining
- drainRefQ()
- }
- }
- drainRefQ()
- }
-
- /** Prints some status information on currently managed actors. */
- protected def status() {
- println(this+": size of refSet: "+refSet.size)
- }
-
- /** Checks whether all actors have terminated. */
- override private[actors] def allActorsTerminated: Boolean = synchronized {
- activeActors <= 0
- }
-
- override def onTerminate(a: TrackedReactor)(f: => Unit): Unit = synchronized {
- terminationHandlers += (a -> (() => f))
- }
-
- override def terminated(a: TrackedReactor) = {
- super.terminated(a)
-
- synchronized {
- // find the weak reference that points to the terminated actor, if any
- refSet.find((ref: Reference[t] forSome { type t <: TrackedReactor }) => ref.get() == a) match {
- case Some(r) =>
- // invoking clear will not cause r to be enqueued
- r.clear()
- refSet -= r.asInstanceOf[Reference[t] forSome { type t <: TrackedReactor }]
- case None =>
- // do nothing
- }
- }
- }
-
- private[actors] def getPendingCount = synchronized {
- activeActors
- }
-
- private[actors] def setPendingCount(cnt: Int) = synchronized {
- activeActors = cnt
- }
-
-}
diff --git a/src/actors/scala/actors/scheduler/DaemonScheduler.scala b/src/actors/scala/actors/scheduler/DaemonScheduler.scala
deleted file mode 100644
index b21a1aa3e6..0000000000
--- a/src/actors/scala/actors/scheduler/DaemonScheduler.scala
+++ /dev/null
@@ -1,34 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala.actors
-package scheduler
-
-/**
- * Default scheduler for actors with daemon semantics, such as those backing futures.
- *
- * @author Erik Engbrecht
- */
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-object DaemonScheduler extends DelegatingScheduler {
-
- protected def makeNewScheduler(): IScheduler = {
- val sched = if (!ThreadPoolConfig.useForkJoin) {
- val s = new ResizableThreadPoolScheduler(true)
- s.start()
- s
- } else {
- val s = new ForkJoinScheduler(true)
- s.start()
- s
- }
- Debug.info(this+": starting new "+sched+" ["+sched.getClass+"]")
- sched
- }
-
-}
diff --git a/src/actors/scala/actors/scheduler/DelegatingScheduler.scala b/src/actors/scala/actors/scheduler/DelegatingScheduler.scala
deleted file mode 100644
index b8a81d11a9..0000000000
--- a/src/actors/scala/actors/scheduler/DelegatingScheduler.scala
+++ /dev/null
@@ -1,74 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala.actors
-package scheduler
-
-import scala.concurrent.ManagedBlocker
-
-/**
- * @author Erik Engbrecht
- */
-private[actors] trait DelegatingScheduler extends IScheduler {
- protected def makeNewScheduler(): IScheduler
-
- protected var sched: IScheduler = null
-
- final def impl = synchronized {
- if ((sched eq null) || (!sched.isActive))
- sched = makeNewScheduler()
- sched
- }
-
- final def impl_= (scheduler: IScheduler): Unit = synchronized {
- //TODO: if there is already a scheduler, should it be shutdown?
- sched = scheduler
- }
-
- /**
- * Always active because it will just make a new scheduler if required
- */
- def isActive: Boolean = true
-
- def execute(fun: => Unit) = impl.execute(fun)
-
- def execute(task: Runnable) = impl.execute(task)
-
- override def executeFromActor(task: Runnable) = impl.executeFromActor(task)
-
- def shutdown(): Unit = synchronized {
- if (sched ne null) {
- sched.shutdown()
- sched = null
- }
- }
-
- def newActor(actor: TrackedReactor) = synchronized {
- val createNew = if (sched eq null)
- true
- else sched.synchronized {
- if (!sched.isActive)
- true
- else {
- sched.newActor(actor)
- false
- }
- }
- if (createNew) {
- sched = makeNewScheduler()
- sched.newActor(actor)
- }
- }
-
- def terminated(actor: TrackedReactor) = impl.terminated(actor)
-
- def onTerminate(actor: TrackedReactor)(f: => Unit) = impl.onTerminate(actor)(f)
-
- override def managedBlock(blocker: ManagedBlocker): Unit =
- impl.managedBlock(blocker)
-}
diff --git a/src/actors/scala/actors/scheduler/DrainableForkJoinPool.scala b/src/actors/scala/actors/scheduler/DrainableForkJoinPool.scala
deleted file mode 100644
index 37710ec037..0000000000
--- a/src/actors/scala/actors/scheduler/DrainableForkJoinPool.scala
+++ /dev/null
@@ -1,11 +0,0 @@
-package scala.actors
-package scheduler
-
-import java.util.Collection
-import scala.concurrent.forkjoin.{ForkJoinPool, ForkJoinTask}
-
-private class DrainableForkJoinPool(parallelism: Int, maxPoolSize: Int) extends ForkJoinPool(parallelism, ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, true) {
-
- override def drainTasksTo(c: Collection[ _ >: ForkJoinTask[_]]): Int =
- super.drainTasksTo(c)
-}
diff --git a/src/actors/scala/actors/scheduler/ExecutorScheduler.scala b/src/actors/scala/actors/scheduler/ExecutorScheduler.scala
deleted file mode 100644
index 4d3ebc3c04..0000000000
--- a/src/actors/scala/actors/scheduler/ExecutorScheduler.scala
+++ /dev/null
@@ -1,95 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-package scala.actors
-package scheduler
-
-import java.util.concurrent.{Callable, ExecutorService}
-import scala.concurrent.ThreadPoolRunner
-
-/**
- * The <code>ExecutorScheduler</code> object is used to create
- * <code>ExecutorScheduler</code> instances.
- *
- * @author Philipp Haller
- */
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-object ExecutorScheduler {
-
- private def start(sched: ExecutorScheduler): ExecutorScheduler = {
- sched.start()
- sched
- }
-
- /** Creates an <code>ExecutorScheduler</code> using the provided
- * <code>ExecutorService</code>.
- *
- * @param exec the executor to use
- * @return the scheduler
- */
- def apply(exec: ExecutorService): ExecutorScheduler =
- start(new ExecutorScheduler {
- val executor: ExecutorService = exec
- })
-
- /** Creates an <code>ExecutorScheduler</code> using the provided
- * <code>ExecutorService</code>.
- *
- * @param exec the executor to use
- * @param term whether the scheduler should automatically terminate
- * @return the scheduler
- */
- def apply(exec: ExecutorService, term: Boolean): ExecutorScheduler =
- start(new ExecutorScheduler {
- val executor: ExecutorService = exec
- override val terminate = term
- })
-
-}
-
-/**
- * The <code>ExecutorScheduler</code> class uses an
- * <code>ExecutorService</code> to execute <code>Actor</code>s.
- *
- * @author Philipp Haller
- */
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-trait ExecutorScheduler extends Thread
- with IScheduler with TerminationService
- with ThreadPoolRunner {
-
- def execute(task: Runnable) {
- super[ThreadPoolRunner].execute(task.asInstanceOf[Task[Unit]])
- }
-
- private class RunCallable(fun: => Unit) extends Callable[Unit] with Runnable {
- def call() { fun }
- def run() { fun }
- }
-
- /** Submits a closure for execution.
- *
- * @param fun the closure to be executed
- */
- override def execute(fun: => Unit) {
- super[ThreadPoolRunner].execute((new RunCallable(fun)).asInstanceOf[Task[Unit]])
- }
-
- /** This method is called when the scheduler shuts down.
- */
- def onShutdown(): Unit =
- executor.shutdown()
-
- /** The scheduler is active if the underlying <code>ExecutorService</code>
- * has not been shut down.
- */
- def isActive =
- (executor ne null) && !executor.isShutdown
-
-}
diff --git a/src/actors/scala/actors/scheduler/ForkJoinScheduler.scala b/src/actors/scala/actors/scheduler/ForkJoinScheduler.scala
deleted file mode 100644
index 75a98db6c8..0000000000
--- a/src/actors/scala/actors/scheduler/ForkJoinScheduler.scala
+++ /dev/null
@@ -1,174 +0,0 @@
-package scala.actors
-package scheduler
-
-import java.util.{Collection, ArrayList}
-import scala.concurrent.forkjoin._
-
-/** The <code>ForkJoinScheduler</code> is backed by a lightweight
- * fork-join task execution framework.
- *
- * @author Philipp Haller
- */
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-class ForkJoinScheduler(val initCoreSize: Int, val maxSize: Int, daemon: Boolean, fair: Boolean)
- extends Runnable with IScheduler with TerminationMonitor {
-
- private var pool = makeNewPool() // guarded by this
- private var terminating = false // guarded by this
- private var snapshoting = false // guarded by this
-
- // this has to be a java.util.Collection, since this is what
- // the ForkJoinPool returns.
- private var drainedTasks: Collection[ForkJoinTask[_]] = null
-
- protected val CHECK_FREQ = 10
-
- // this random number generator is only used in fair mode
- private lazy val random = new java.util.Random // guarded by random
-
- def this(d: Boolean, f: Boolean) {
- this(ThreadPoolConfig.corePoolSize, ThreadPoolConfig.maxPoolSize, d, f)
- }
-
- def this(d: Boolean) {
- this(d, true) // default is fair
- }
-
- def this() {
- this(false) // default is non-daemon
- }
-
- private def makeNewPool(): DrainableForkJoinPool = {
- val p = new DrainableForkJoinPool(initCoreSize, maxSize)
- Debug.info(this+": parallelism "+p.getParallelism())
- p
- }
-
- /** Starts this scheduler.
- */
- def start() {
- try {
- val t = new Thread(this)
- t.setDaemon(daemon)
- t.setName("ForkJoinScheduler")
- t.start()
- } catch {
- case e: Exception =>
- Debug.info(this+": could not create scheduler thread: "+e)
- }
- }
-
- override def run() {
- try {
- while (true) {
- this.synchronized {
- try {
- wait(CHECK_FREQ.toLong)
- } catch {
- case _: InterruptedException =>
- }
-
- if (terminating)
- throw new QuitControl
-
- if (allActorsTerminated) {
- Debug.info(this+": all actors terminated")
- terminating = true
- throw new QuitControl
- }
-
- if (!snapshoting) {
- gc()
- } else if (pool.isQuiescent()) {
- val list = new ArrayList[ForkJoinTask[_]]
- val num = pool.drainTasksTo(list)
- Debug.info(this+": drained "+num+" tasks")
- drainedTasks = list
- terminating = true
- throw new QuitControl
- }
- }
- }
- } catch {
- case _: QuitControl =>
- Debug.info(this+": initiating shutdown...")
- while (!pool.isQuiescent()) {
- try {
- Thread.sleep(10)
- } catch {
- case ignore: InterruptedException =>
- }
- }
- pool.shutdown()
- // allow thread to exit
- }
- }
-
- // TODO: when do we pass a task that is not a RecursiveAction?
- def execute(task: Runnable) {
- pool.execute(task)
- }
-
- override def executeFromActor(task: Runnable) {
- // in fair mode: 2% chance of submitting to global task queue
- if (fair && random.synchronized { random.nextInt(50) == 1 })
- pool.execute(task)
- else
- task.asInstanceOf[RecursiveAction].fork()
- }
-
- /** Submits a closure for execution.
- *
- * @param fun the closure to be executed
- */
- def execute(fun: => Unit): Unit =
- execute(new Runnable {
- def run() { fun }
- })
-
- /** Shuts down the scheduler.
- */
- def shutdown(): Unit = synchronized {
- terminating = true
- }
-
- def isActive = synchronized {
- !terminating && (pool ne null) && !pool.isShutdown()
- }
-
- override def managedBlock(blocker: scala.concurrent.ManagedBlocker) {
- ForkJoinPool.managedBlock(new ForkJoinPool.ManagedBlocker {
- def block = blocker.block()
- def isReleasable() = blocker.isReleasable
- })
- }
-
- /** Suspends the scheduler. All threads that were in use by the
- * scheduler and its internal thread pool are terminated.
- */
- def snapshot() = synchronized {
- snapshoting = true
- }
-
- /** Resumes the execution of the scheduler if it was previously
- * suspended using <code>ForkJoinScheduler.snapshot</code>.
- */
- def restart() {
- synchronized {
- if (!snapshoting)
- sys.error("snapshot has not been invoked")
- else if (isActive)
- sys.error("scheduler is still active")
- else
- snapshoting = false
-
- pool = makeNewPool()
- }
- val iter = drainedTasks.iterator()
- while (iter.hasNext()) {
- pool.execute(iter.next())
- }
- start()
- }
-
-}
diff --git a/src/actors/scala/actors/scheduler/QuitControl.scala b/src/actors/scala/actors/scheduler/QuitControl.scala
deleted file mode 100644
index b3e288aaff..0000000000
--- a/src/actors/scala/actors/scheduler/QuitControl.scala
+++ /dev/null
@@ -1,19 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala.actors.scheduler
-
-import scala.util.control.ControlThrowable
-
-/**
- * The `QuitControl` class is used to manage control flow of certain
- * schedulers.
- *
- * @author Philipp Haller
- */
-private[scheduler] class QuitControl extends ControlThrowable
diff --git a/src/actors/scala/actors/scheduler/ResizableThreadPoolScheduler.scala b/src/actors/scala/actors/scheduler/ResizableThreadPoolScheduler.scala
deleted file mode 100644
index 342579db6c..0000000000
--- a/src/actors/scala/actors/scheduler/ResizableThreadPoolScheduler.scala
+++ /dev/null
@@ -1,197 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala.actors.scheduler
-
-import scala.actors.threadpool.{ThreadPoolExecutor, TimeUnit, LinkedBlockingQueue,
- ThreadFactory}
-import scala.actors.{Debug, IScheduler}
-import scala.concurrent.ManagedBlocker
-
-/**
- * This scheduler class uses a `ThreadPoolExecutor` to execute `Actor`s.
- *
- * The scheduler attempts to shut down itself and the underlying
- * `ThreadPoolExecutor` only if `terminate` is set to true. Otherwise,
- * the scheduler must be shut down explicitly.
- *
- * @author Philipp Haller
- */
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-class ResizableThreadPoolScheduler(protected val terminate: Boolean,
- protected val daemon: Boolean)
- extends Thread with IScheduler with TerminationMonitor {
-
- setDaemon(daemon)
-
- // guarded by this
- private var terminating = false
- // guarded by this
- private var suspending = false
-
- // this has to be a java.util.Collection, since this is what
- // the ForkJoinPool returns.
- @volatile
- private var drainedTasks: java.util.List[_] = null
-
- // guarded by this
- private var coreSize = ThreadPoolConfig.corePoolSize
- private val maxSize = ThreadPoolConfig.maxPoolSize
- private val numCores = Runtime.getRuntime().availableProcessors()
-
- protected val CHECK_FREQ = 10
-
- private class DaemonThreadFactory extends ThreadFactory {
- def newThread(r: Runnable): Thread = {
- val t = new Thread(r)
- t.setDaemon(daemon)
- t
- }
- }
- private val threadFac = new DaemonThreadFactory
-
- private def makeNewPool(): ThreadPoolExecutor = {
- val workQueue = new LinkedBlockingQueue
- new ThreadPoolExecutor(coreSize,
- maxSize,
- 60000L,
- TimeUnit.MILLISECONDS,
- workQueue,
- threadFac,
- new ThreadPoolExecutor.CallerRunsPolicy)
- }
-
- // guarded by this
- private var executor = makeNewPool()
-
- Debug.info(this+": corePoolSize = "+coreSize+", maxPoolSize = "+maxSize)
-
- def this(d: Boolean) {
- this(true, d)
- }
-
- def this() {
- this(false)
- }
-
- private def numWorkersBlocked = {
- executor.mainLock.lock()
- val iter = executor.workers.iterator()
- var numBlocked = 0
- while (iter.hasNext()) {
- val w = iter.next().asInstanceOf[ThreadPoolExecutor#Worker]
- if (w.tryLock()) {
- // worker is idle
- w.unlock()
- } else {
- val s = w.thread.getState()
- if (s == Thread.State.WAITING || s == Thread.State.TIMED_WAITING)
- numBlocked += 1
- }
- }
- executor.mainLock.unlock()
- numBlocked
- }
-
- override def run() {
- try {
- while (true) {
- this.synchronized {
- try {
- wait(CHECK_FREQ.toLong)
- } catch {
- case _: InterruptedException =>
- }
-
- if (terminating)
- throw new QuitControl
-
- if (!suspending) {
- gc()
-
- // check if we need more worker threads
- val activeBlocked = numWorkersBlocked
- if (coreSize - activeBlocked < numCores && coreSize < maxSize) {
- coreSize = numCores + activeBlocked
- executor.setCorePoolSize(coreSize)
- } else if (terminate && allActorsTerminated) {
- // if all worker threads idle terminate
- if (executor.getActiveCount() == 0) {
- Debug.info(this+": initiating shutdown...")
- Debug.info(this+": corePoolSize = "+coreSize+", maxPoolSize = "+maxSize)
-
- terminating = true
- throw new QuitControl
- }
- }
- } else {
- drainedTasks = executor.shutdownNow()
- Debug.info(this+": drained "+drainedTasks.size()+" tasks")
- terminating = true
- throw new QuitControl
- }
- } // sync
- }
- } catch {
- case _: QuitControl =>
- executor.shutdown()
- // allow thread to exit
- }
- }
-
- def execute(task: Runnable): Unit =
- executor execute task
-
- def execute(fun: => Unit): Unit =
- executor.execute(new Runnable {
- def run() { fun }
- })
-
- /** Shuts down the scheduler.
- */
- def shutdown(): Unit = synchronized {
- terminating = true
- }
-
- def isActive = synchronized {
- !terminating && (executor ne null) && !executor.isShutdown()
- }
-
- def managedBlock(blocker: ManagedBlocker) {
- blocker.block()
- }
-
- /** Suspends the scheduler. All threads that were in use by the
- * scheduler and its internal thread pool are terminated.
- */
- def snapshot() = synchronized {
- suspending = true
- }
-
- /** Resumes the execution of the scheduler if it was previously
- * suspended using `snapshot`.
- */
- def restart() {
- synchronized {
- if (!suspending)
- sys.error("snapshot has not been invoked")
- else if (isActive)
- sys.error("scheduler is still active")
- else
- suspending = false
-
- executor = makeNewPool()
- }
- val iter = drainedTasks.iterator()
- while (iter.hasNext()) {
- executor.execute(iter.next().asInstanceOf[Runnable])
- }
- start()
- }
-
-}
diff --git a/src/actors/scala/actors/scheduler/SingleThreadedScheduler.scala b/src/actors/scala/actors/scheduler/SingleThreadedScheduler.scala
deleted file mode 100644
index 03b235fe74..0000000000
--- a/src/actors/scala/actors/scheduler/SingleThreadedScheduler.scala
+++ /dev/null
@@ -1,69 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-package scala.actors
-package scheduler
-
-import scala.collection.mutable
-
-/**
- * This scheduler executes actor tasks on the current thread.
- *
- * @author Philipp Haller
- */
-@deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0")
-class SingleThreadedScheduler extends IScheduler {
-
- private val tasks = new mutable.Queue[Runnable]
-
- /** The maximum number of nested tasks that are run
- * without unwinding the call stack.
- */
- protected val maxNesting = 10
-
- private var curNest = 0
- private var isShutdown = false
-
- def execute(task: Runnable) {
- if (curNest < maxNesting) {
- curNest += 1
- task.run()
- } else {
- curNest = 0
- tasks += task
- }
- }
-
- def execute(fun: => Unit): Unit =
- execute(new Runnable {
- def run() { fun }
- })
-
- def shutdown() {
- isShutdown = false
- while (!tasks.isEmpty) {
- val task = tasks.dequeue()
- task.run()
- }
- isShutdown = true
- }
-
- def newActor(actor: TrackedReactor) {}
- def terminated(actor: TrackedReactor) {}
-
- // TODO: run termination handlers at end of shutdown.
- def onTerminate(actor: TrackedReactor)(f: => Unit) {}
-
- def isActive =
- !isShutdown
-
- def managedBlock(blocker: scala.concurrent.ManagedBlocker) {
- blocker.block()
- }
-}
diff --git a/src/actors/scala/actors/scheduler/TerminationMonitor.scala b/src/actors/scala/actors/scheduler/TerminationMonitor.scala
deleted file mode 100644
index 9f26ca8d69..0000000000
--- a/src/actors/scala/actors/scheduler/TerminationMonitor.scala
+++ /dev/null
@@ -1,69 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala.actors
-package scheduler
-
-import scala.collection.mutable
-
-private[scheduler] trait TerminationMonitor {
- _: IScheduler =>
-
- protected var activeActors = 0
- protected val terminationHandlers = new mutable.HashMap[TrackedReactor, () => Unit]
- private var started = false
-
- /** newActor is invoked whenever a new actor is started. */
- def newActor(a: TrackedReactor) = synchronized {
- activeActors += 1
- if (!started)
- started = true
- }
-
- /** Registers a closure to be executed when the specified
- * actor terminates.
- *
- * @param a the actor
- * @param f the closure to be registered
- */
- def onTerminate(a: TrackedReactor)(f: => Unit): Unit = synchronized {
- terminationHandlers += (a -> (() => f))
- }
-
- /** Registers that the specified actor has terminated.
- *
- * @param a the actor that has terminated
- */
- def terminated(a: TrackedReactor) = {
- // obtain termination handler (if any)
- val todo = synchronized {
- terminationHandlers.get(a) match {
- case Some(handler) =>
- terminationHandlers -= a
- handler
- case None =>
- () => { /* do nothing */ }
- }
- }
-
- // invoke termination handler (if any)
- todo()
-
- synchronized {
- activeActors -= 1
- }
- }
-
- /** Checks whether all actors have terminated. */
- private[actors] def allActorsTerminated: Boolean = synchronized {
- started && activeActors <= 0
- }
-
- /** Checks for actors that have become garbage. */
- protected def gc() {}
-}
diff --git a/src/actors/scala/actors/scheduler/TerminationService.scala b/src/actors/scala/actors/scheduler/TerminationService.scala
deleted file mode 100644
index ed1805ee1e..0000000000
--- a/src/actors/scala/actors/scheduler/TerminationService.scala
+++ /dev/null
@@ -1,68 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-package scala.actors
-package scheduler
-
-import java.lang.{Thread, InterruptedException}
-
-/**
- * The <code>TerminationService</code> class starts a new thread
- * that is used to check regularly if the scheduler can be
- * shut down, because all started actors are known to
- * have terminated.
- *
- * @author Philipp Haller
- */
-private[scheduler] trait TerminationService extends TerminationMonitor {
- _: Thread with IScheduler =>
-
- private var terminating = false
-
- /** Indicates whether the scheduler should terminate when all
- * actors have terminated.
- */
- protected val terminate = true
-
- protected val CHECK_FREQ = 50
-
- def onShutdown(): Unit
-
- override def run() {
- try {
- while (true) {
- this.synchronized {
- try {
- wait(CHECK_FREQ.toLong)
- } catch {
- case _: InterruptedException =>
- }
-
- if (terminating || (terminate && allActorsTerminated))
- throw new QuitControl
-
- gc()
- }
- }
- } catch {
- case _: QuitControl =>
- Debug.info(this+": initiating shutdown...")
- // invoke shutdown hook
- onShutdown()
- // allow thread to exit
- }
- }
-
- /** Shuts down the scheduler.
- */
- def shutdown(): Unit = synchronized {
- terminating = true
- }
-
-}
diff --git a/src/actors/scala/actors/scheduler/ThreadPoolConfig.scala b/src/actors/scala/actors/scheduler/ThreadPoolConfig.scala
deleted file mode 100644
index bfd4e7ac40..0000000000
--- a/src/actors/scala/actors/scheduler/ThreadPoolConfig.scala
+++ /dev/null
@@ -1,50 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-package scala.actors
-package scheduler
-
-import scala.util.Properties.{ javaVersion, javaVmVendor, isJavaAtLeast, propIsSetTo, propOrNone }
-
-/**
- * @author Erik Engbrecht
- * @author Philipp Haller
- */
-private[actors] object ThreadPoolConfig {
- private val rt = Runtime.getRuntime()
- private val minNumThreads = 4
-
- private def getIntegerProp(propName: String): Option[Int] =
- try propOrNone(propName) map (_.toInt)
- catch { case _: SecurityException | _: NumberFormatException => None }
-
- val corePoolSize = getIntegerProp("actors.corePoolSize") match {
- case Some(i) if i > 0 => i
- case _ => {
- val byCores = rt.availableProcessors() * 2
- if (byCores > minNumThreads) byCores else minNumThreads
- }
- }
-
- val maxPoolSize = {
- val preMaxSize = getIntegerProp("actors.maxPoolSize") getOrElse 256
- if (preMaxSize >= corePoolSize) preMaxSize else corePoolSize
- }
-
- private[actors] def useForkJoin: Boolean =
- try !propIsSetTo("actors.enableForkJoin", "false") &&
- (propIsSetTo("actors.enableForkJoin", "true") || {
- Debug.info(this+": java.version = "+javaVersion)
- Debug.info(this+": java.vm.vendor = "+javaVmVendor)
- isJavaAtLeast("1.6")
- })
- catch {
- case _: SecurityException => false
- }
-}
diff --git a/src/actors/scala/actors/threadpool/AbstractCollection.java b/src/actors/scala/actors/threadpool/AbstractCollection.java
deleted file mode 100644
index 195a0064ab..0000000000
--- a/src/actors/scala/actors/threadpool/AbstractCollection.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Written by Dawid Kurzyniec, based on public domain code written by Doug Lea
- * and publicly available documentation, and released to the public domain, as
- * explained at http://creativecommons.org/licenses/publicdomain
- */
-
-package scala.actors.threadpool;
-import scala.actors.threadpool.helpers.Utils;
-
-/**
- * Overrides toArray() and toArray(Object[]) in AbstractCollection to provide
- * implementations valid for concurrent collections.
- *
- * @author Doug Lea
- * @author Dawid Kurzyniec
- */
-public abstract class AbstractCollection extends java.util.AbstractCollection {
-
- /**
- * Sole constructor. (For invocation by subclass constructors, typically
- * implicit.)
- */
- protected AbstractCollection() { super(); }
-
- public Object[] toArray() {
- return Utils.collectionToArray(this);
- }
-
- public Object[] toArray(Object[] a) {
- return Utils.collectionToArray(this, a);
- }
-}
diff --git a/src/actors/scala/actors/threadpool/AbstractExecutorService.java b/src/actors/scala/actors/threadpool/AbstractExecutorService.java
deleted file mode 100644
index 4a12aa3c28..0000000000
--- a/src/actors/scala/actors/threadpool/AbstractExecutorService.java
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
- */
-
-package scala.actors.threadpool;
-
-import scala.actors.threadpool.helpers.*;
-import java.util.Collection;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Iterator;
-
-/**
- * Provides default implementations of {@link ExecutorService}
- * execution methods. This class implements the <tt>submit</tt>,
- * <tt>invokeAny</tt> and <tt>invokeAll</tt> methods using a
- * {@link RunnableFuture} returned by <tt>newTaskFor</tt>, which defaults
- * to the {@link FutureTask} class provided in this package. For example,
- * the implementation of <tt>submit(Runnable)</tt> creates an
- * associated <tt>RunnableFuture</tt> that is executed and
- * returned. Subclasses may override the <tt>newTaskFor</tt> methods
- * to return <tt>RunnableFuture</tt> implementations other than
- * <tt>FutureTask</tt>.
- *
- * <p> <b>Extension example</b>. Here is a sketch of a class
- * that customizes {@link ThreadPoolExecutor} to use
- * a <tt>CustomTask</tt> class instead of the default <tt>FutureTask</tt>:
- * <pre>
- * public class CustomThreadPoolExecutor extends ThreadPoolExecutor {
- *
- * static class CustomTask&lt;V&gt; implements RunnableFuture&lt;V&gt; {...}
- *
- * protected &lt;V&gt; RunnableFuture&lt;V&gt; newTaskFor(Callable&lt;V&gt; c) {
- * return new CustomTask&lt;V&gt;(c);
- * }
- * protected &lt;V&gt; RunnableFuture&lt;V&gt; newTaskFor(Runnable r, V v) {
- * return new CustomTask&lt;V&gt;(r, v);
- * }
- * // ... add constructors, etc.
- * }
- * </pre>
- * @since 1.5
- * @author Doug Lea
- */
-public abstract class AbstractExecutorService implements ExecutorService {
-
- /**
- * Returns a <tt>RunnableFuture</tt> for the given runnable and default
- * value.
- *
- * @param runnable the runnable task being wrapped
- * @param value the default value for the returned future
- * @return a <tt>RunnableFuture</tt> which when run will run the
- * underlying runnable and which, as a <tt>Future</tt>, will yield
- * the given value as its result and provide for cancellation of
- * the underlying task.
- * @since 1.6
- */
- protected RunnableFuture newTaskFor(Runnable runnable, Object value) {
- return new FutureTask(runnable, value);
- }
-
- /**
- * Returns a <tt>RunnableFuture</tt> for the given callable task.
- *
- * @param callable the callable task being wrapped
- * @return a <tt>RunnableFuture</tt> which when run will call the
- * underlying callable and which, as a <tt>Future</tt>, will yield
- * the callable's result as its result and provide for
- * cancellation of the underlying task.
- * @since 1.6
- */
- protected RunnableFuture newTaskFor(Callable callable) {
- return new FutureTask(callable);
- }
-
- /**
- * @throws RejectedExecutionException {@inheritDoc}
- * @throws NullPointerException {@inheritDoc}
- */
- public Future submit(Runnable task) {
- if (task == null) throw new NullPointerException();
- RunnableFuture ftask = newTaskFor(task, null);
- execute(ftask);
- return ftask;
- }
-
- /**
- * @throws RejectedExecutionException {@inheritDoc}
- * @throws NullPointerException {@inheritDoc}
- */
- public Future submit(Runnable task, Object result) {
- if (task == null) throw new NullPointerException();
- RunnableFuture ftask = newTaskFor(task, result);
- execute(ftask);
- return ftask;
- }
-
- /**
- * @throws RejectedExecutionException {@inheritDoc}
- * @throws NullPointerException {@inheritDoc}
- */
- public Future submit(Callable task) {
- if (task == null) throw new NullPointerException();
- RunnableFuture ftask = newTaskFor(task);
- execute(ftask);
- return ftask;
- }
-
- /**
- * the main mechanics of invokeAny.
- */
- private Object doInvokeAny(Collection tasks,
- boolean timed, long nanos)
- throws InterruptedException, ExecutionException, TimeoutException {
- if (tasks == null)
- throw new NullPointerException();
- int ntasks = tasks.size();
- if (ntasks == 0)
- throw new IllegalArgumentException();
- List<Future> futures = new ArrayList<Future>(ntasks);
- ExecutorCompletionService ecs =
- new ExecutorCompletionService(this);
-
- // For efficiency, especially in executors with limited
- // parallelism, check to see if previously submitted tasks are
- // done before submitting more of them. This interleaving
- // plus the exception mechanics account for messiness of main
- // loop.
-
- try {
- // Record exceptions so that if we fail to obtain any
- // result, we can throw the last exception we got.
- ExecutionException ee = null;
- long lastTime = (timed)? Utils.nanoTime() : 0;
- Iterator it = tasks.iterator();
-
- // Start one task for sure; the rest incrementally
- futures.add(ecs.submit((Callable)it.next()));
- --ntasks;
- int active = 1;
-
- for (;;) {
- Future f = ecs.poll();
- if (f == null) {
- if (ntasks > 0) {
- --ntasks;
- futures.add(ecs.submit((Callable)it.next()));
- ++active;
- }
- else if (active == 0)
- break;
- else if (timed) {
- f = ecs.poll(nanos, TimeUnit.NANOSECONDS);
- if (f == null)
- throw new TimeoutException();
- long now = Utils.nanoTime();
- nanos -= now - lastTime;
- lastTime = now;
- }
- else
- f = ecs.take();
- }
- if (f != null) {
- --active;
- try {
- return f.get();
- } catch (InterruptedException ie) {
- throw ie;
- } catch (ExecutionException eex) {
- ee = eex;
- } catch (RuntimeException rex) {
- ee = new ExecutionException(rex);
- }
- }
- }
-
- if (ee == null)
- ee = new ExecutionException();
- throw ee;
-
- } finally {
- for (Iterator f = futures.iterator(); f.hasNext();)
- ((Future)f.next()).cancel(true);
- }
- }
-
- public Object invokeAny(Collection tasks)
- throws InterruptedException, ExecutionException {
- try {
- return doInvokeAny(tasks, false, 0);
- } catch (TimeoutException cannotHappen) {
- assert false;
- return null;
- }
- }
-
- public Object invokeAny(Collection tasks,
- long timeout, TimeUnit unit)
- throws InterruptedException, ExecutionException, TimeoutException {
- return doInvokeAny(tasks, true, unit.toNanos(timeout));
- }
-
- public List<Future> invokeAll(Collection tasks) throws InterruptedException {
- if (tasks == null)
- throw new NullPointerException();
- List<Future> futures = new ArrayList<Future>(tasks.size());
- boolean done = false;
- try {
- for (Iterator t = tasks.iterator(); t.hasNext();) {
- RunnableFuture f = newTaskFor((Callable)t.next());
- futures.add(f);
- execute(f);
- }
- for (Iterator i = futures.iterator(); i.hasNext();) {
- Future f = (Future) i.next();
- if (!f.isDone()) {
- try {
- f.get();
- } catch (CancellationException ignore) {
- } catch (ExecutionException ignore) {
- }
- }
- }
- done = true;
- return futures;
- } finally {
- if (!done)
- for (Iterator i = futures.iterator(); i.hasNext();) {
- Future f = (Future) i.next();
- f.cancel(true);
- }
- }
- }
-
- public List<Future> invokeAll(Collection tasks,
- long timeout, TimeUnit unit)
- throws InterruptedException {
- if (tasks == null || unit == null)
- throw new NullPointerException();
- long nanos = unit.toNanos(timeout);
- List<Future> futures = new ArrayList<Future>(tasks.size());
- boolean done = false;
- try {
- for (Iterator t = tasks.iterator(); t.hasNext();)
- futures.add(newTaskFor((Callable)t.next()));
-
- long lastTime = Utils.nanoTime();
-
- // Interleave time checks and calls to execute in case
- // executor doesn't have any/much parallelism.
- Iterator it = futures.iterator();
- while (it.hasNext()) {
- execute((Runnable)(it.next()));
- long now = Utils.nanoTime();
- nanos -= (now - lastTime);
- lastTime = now;
- if (nanos <= 0)
- return futures;
- }
-
- for (Iterator i = futures.iterator(); i.hasNext();) {
- Future f = (Future)i.next();
- if (!f.isDone()) {
- if (nanos <= 0)
- return futures;
- try {
- f.get(nanos, TimeUnit.NANOSECONDS);
- } catch (CancellationException ignore) {
- } catch (ExecutionException ignore) {
- } catch (TimeoutException toe) {
- return futures;
- }
- long now = Utils.nanoTime();
- nanos -= now - lastTime;
- lastTime = now;
- }
- }
- done = true;
- return futures;
- } finally {
- if (!done)
- for (Iterator i = futures.iterator(); i.hasNext();) {
- Future f = (Future) i.next();
- f.cancel(true);
- }
- }
- }
-
-}
diff --git a/src/actors/scala/actors/threadpool/AbstractQueue.java b/src/actors/scala/actors/threadpool/AbstractQueue.java
deleted file mode 100644
index 84ddc136bc..0000000000
--- a/src/actors/scala/actors/threadpool/AbstractQueue.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
- */
-
-package scala.actors.threadpool;
-
-import java.util.Iterator;
-import java.util.Collection;
-import java.util.NoSuchElementException;
-
-/**
- * This class provides skeletal implementations of some {@link Queue}
- * operations. The implementations in this class are appropriate when
- * the base implementation does <em>not</em> allow <tt>null</tt>
- * elements. Methods {@link #add add}, {@link #remove remove}, and
- * {@link #element element} are based on {@link #offer offer}, {@link
- * #poll poll}, and {@link #peek peek}, respectively but throw
- * exceptions instead of indicating failure via <tt>false</tt> or
- * <tt>null</tt> returns.
- *
- * <p> A <tt>Queue</tt> implementation that extends this class must
- * minimally define a method {@link Queue#offer} which does not permit
- * insertion of <tt>null</tt> elements, along with methods {@link
- * Queue#peek}, {@link Queue#poll}, {@link Collection#size}, and a
- * {@link Collection#iterator} supporting {@link
- * Iterator#remove}. Typically, additional methods will be overridden
- * as well. If these requirements cannot be met, consider instead
- * subclassing {@link AbstractCollection}.
- *
- * <p>This class is a member of the
- * <a href="{@docRoot}/../technotes/guides/collections/index.html">
- * Java Collections Framework</a>.
- *
- * @since 1.5
- * @author Doug Lea
- */
-public abstract class AbstractQueue
- extends AbstractCollection
- implements Queue {
-
- /**
- * Constructor for use by subclasses.
- */
- protected AbstractQueue() {
- }
-
- /**
- * Inserts the specified element into this queue if it is possible to do so
- * immediately without violating capacity restrictions, returning
- * <tt>true</tt> upon success and throwing an <tt>IllegalStateException</tt>
- * if no space is currently available.
- *
- * <p>This implementation returns <tt>true</tt> if <tt>offer</tt> succeeds,
- * else throws an <tt>IllegalStateException</tt>.
- *
- * @param e the element to add
- * @return <tt>true</tt> (as specified by {@link Collection#add})
- * @throws IllegalStateException if the element cannot be added at this
- * time due to capacity restrictions
- * @throws ClassCastException if the class of the specified element
- * prevents it from being added to this queue
- * @throws NullPointerException if the specified element is null and
- * this queue does not permit null elements
- * @throws IllegalArgumentException if some property of this element
- * prevents it from being added to this queue
- */
- public boolean add(Object e) {
- if (offer(e))
- return true;
- else
- throw new IllegalStateException("Queue full");
- }
-
- /**
- * Retrieves and removes the head of this queue. This method differs
- * from {@link #poll poll} only in that it throws an exception if this
- * queue is empty.
- *
- * <p>This implementation returns the result of <tt>poll</tt>
- * unless the queue is empty.
- *
- * @return the head of this queue
- * @throws NoSuchElementException if this queue is empty
- */
- public Object remove() {
- Object x = poll();
- if (x != null)
- return x;
- else
- throw new NoSuchElementException();
- }
-
-
- /**
- * Retrieves, but does not remove, the head of this queue. This method
- * differs from {@link #peek peek} only in that it throws an exception if
- * this queue is empty.
- *
- * <p>This implementation returns the result of <tt>peek</tt>
- * unless the queue is empty.
- *
- * @return the head of this queue
- * @throws NoSuchElementException if this queue is empty
- */
- public Object element() {
- Object x = peek();
- if (x != null)
- return x;
- else
- throw new NoSuchElementException();
- }
-
- /**
- * Removes all of the elements from this queue.
- * The queue will be empty after this call returns.
- *
- * <p>This implementation repeatedly invokes {@link #poll poll} until it
- * returns <tt>null</tt>.
- */
- public void clear() {
- while (poll() != null)
- ;
- }
-
- /**
- * Adds all of the elements in the specified collection to this
- * queue. Attempts to addAll of a queue to itself result in
- * <tt>IllegalArgumentException</tt>. Further, the behavior of
- * this operation is undefined if the specified collection is
- * modified while the operation is in progress.
- *
- * <p>This implementation iterates over the specified collection,
- * and adds each element returned by the iterator to this
- * queue, in turn. A runtime exception encountered while
- * trying to add an element (including, in particular, a
- * <tt>null</tt> element) may result in only some of the elements
- * having been successfully added when the associated exception is
- * thrown.
- *
- * @param c collection containing elements to be added to this queue
- * @return <tt>true</tt> if this queue changed as a result of the call
- * @throws ClassCastException if the class of an element of the specified
- * collection prevents it from being added to this queue
- * @throws NullPointerException if the specified collection contains a
- * null element and this queue does not permit null elements,
- * or if the specified collection is null
- * @throws IllegalArgumentException if some property of an element of the
- * specified collection prevents it from being added to this
- * queue, or if the specified collection is this queue
- * @throws IllegalStateException if not all the elements can be added at
- * this time due to insertion restrictions
- * @see #add(Object)
- */
- public boolean addAll(Collection c) {
- if (c == null)
- throw new NullPointerException();
- if (c == this)
- throw new IllegalArgumentException();
- boolean modified = false;
- Iterator e = c.iterator();
- while (e.hasNext()) {
- if (add(e.next()))
- modified = true;
- }
- return modified;
- }
-
-}
diff --git a/src/actors/scala/actors/threadpool/Arrays.java b/src/actors/scala/actors/threadpool/Arrays.java
deleted file mode 100644
index 85e7c8fa00..0000000000
--- a/src/actors/scala/actors/threadpool/Arrays.java
+++ /dev/null
@@ -1,811 +0,0 @@
-/*
- * Written by Dawid Kurzyniec, based on code written by Doug Lea with assistance
- * from members of JCP JSR-166 Expert Group. Released to the public domain,
- * as explained at http://creativecommons.org/licenses/publicdomain.
- */
-
-package scala.actors.threadpool;
-
-import java.lang.reflect.Array;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Comparator;
-
-public class Arrays {
-
- private Arrays() {}
-
- public static void sort(long[] a) {
- java.util.Arrays.sort(a);
- }
-
- public static void sort(long[] a, int fromIndex, int toIndex) {
- java.util.Arrays.sort(a, fromIndex, toIndex);
- }
-
- public static void sort(int[] a) {
- java.util.Arrays.sort(a);
- }
-
- public static void sort(int[] a, int fromIndex, int toIndex) {
- java.util.Arrays.sort(a, fromIndex, toIndex);
- }
-
- public static void sort(short[] a) {
- java.util.Arrays.sort(a);
- }
-
- public static void sort(short[] a, int fromIndex, int toIndex) {
- java.util.Arrays.sort(a, fromIndex, toIndex);
- }
-
- public static void sort(char[] a) {
- java.util.Arrays.sort(a);
- }
-
- public static void sort(char[] a, int fromIndex, int toIndex) {
- java.util.Arrays.sort(a, fromIndex, toIndex);
- }
-
- public static void sort(byte[] a) {
- java.util.Arrays.sort(a);
- }
-
- public static void sort(byte[] a, int fromIndex, int toIndex) {
- java.util.Arrays.sort(a, fromIndex, toIndex);
- }
-
- public static void sort(double[] a) {
- java.util.Arrays.sort(a);
- }
-
- public static void sort(double[] a, int fromIndex, int toIndex) {
- java.util.Arrays.sort(a, fromIndex, toIndex);
- }
-
- public static void sort(float[] a) {
- java.util.Arrays.sort(a);
- }
-
- public static void sort(float[] a, int fromIndex, int toIndex) {
- java.util.Arrays.sort(a, fromIndex, toIndex);
- }
-
-
- public static void sort(Object[] a) {
- java.util.Arrays.sort(a);
- }
-
- public static void sort(Object[] a, int fromIndex, int toIndex) {
- java.util.Arrays.sort(a, fromIndex, toIndex);
- }
-
- public static void sort(Object[] a, Comparator c) {
- java.util.Arrays.sort(a, c);
- }
-
- public static void sort(Object[] a, int fromIndex, int toIndex, Comparator c) {
- java.util.Arrays.sort(a, fromIndex, toIndex, c);
- }
-
-
- // Searching
-
- public static int binarySearch(long[] a, long key) {
- return java.util.Arrays.binarySearch(a, key);
- }
-
- public static int binarySearch(int[] a, int key) {
- return java.util.Arrays.binarySearch(a, key);
- }
-
- public static int binarySearch(short[] a, short key) {
- return java.util.Arrays.binarySearch(a, key);
- }
-
- public static int binarySearch(char[] a, char key) {
- return java.util.Arrays.binarySearch(a, key);
- }
-
- public static int binarySearch(byte[] a, byte key) {
- return java.util.Arrays.binarySearch(a, key);
- }
-
- public static int binarySearch(double[] a, double key) {
- return java.util.Arrays.binarySearch(a, key);
- }
-
- public static int binarySearch(float[] a, float key) {
- return java.util.Arrays.binarySearch(a, key);
- }
-
- public static int binarySearch(Object[] a, Object key) {
- return java.util.Arrays.binarySearch(a, key);
- }
-
- public static int binarySearch(Object[] a, Object key, Comparator c) {
- return java.util.Arrays.binarySearch(a, key, c);
- }
-
-
- // Equality Testing
-
- public static boolean equals(long[] a, long[] a2) {
- return java.util.Arrays.equals(a, a2);
- }
-
- public static boolean equals(int[] a, int[] a2) {
- return java.util.Arrays.equals(a, a2);
- }
-
- public static boolean equals(short[] a, short a2[]) {
- return java.util.Arrays.equals(a, a2);
- }
-
- public static boolean equals(char[] a, char[] a2) {
- return java.util.Arrays.equals(a, a2);
- }
-
- public static boolean equals(byte[] a, byte[] a2) {
- return java.util.Arrays.equals(a, a2);
- }
-
- public static boolean equals(boolean[] a, boolean[] a2) {
- return java.util.Arrays.equals(a, a2);
- }
-
- public static boolean equals(double[] a, double[] a2) {
- return java.util.Arrays.equals(a, a2);
- }
-
- public static boolean equals(float[] a, float[] a2) {
- return java.util.Arrays.equals(a, a2);
- }
-
- public static boolean equals(Object[] a, Object[] a2) {
- return java.util.Arrays.equals(a, a2);
- }
-
-
- // Filling
-
- public static void fill(long[] a, long val) {
- java.util.Arrays.fill(a, val);
- }
-
- public static void fill(long[] a, int fromIndex, int toIndex, long val) {
- java.util.Arrays.fill(a, fromIndex, toIndex, val);
- }
-
- public static void fill(int[] a, int val) {
- java.util.Arrays.fill(a, val);
- }
-
- public static void fill(int[] a, int fromIndex, int toIndex, int val) {
- java.util.Arrays.fill(a, fromIndex, toIndex, val);
- }
-
- public static void fill(short[] a, short val) {
- java.util.Arrays.fill(a, val);
- }
-
- public static void fill(short[] a, int fromIndex, int toIndex, short val) {
- java.util.Arrays.fill(a, fromIndex, toIndex, val);
- }
-
- public static void fill(char[] a, char val) {
- java.util.Arrays.fill(a, val);
- }
-
- public static void fill(char[] a, int fromIndex, int toIndex, char val) {
- java.util.Arrays.fill(a, fromIndex, toIndex, val);
- }
-
- public static void fill(byte[] a, byte val) {
- java.util.Arrays.fill(a, val);
- }
-
- public static void fill(byte[] a, int fromIndex, int toIndex, byte val) {
- java.util.Arrays.fill(a, fromIndex, toIndex, val);
- }
-
- public static void fill(boolean[] a, boolean val) {
- java.util.Arrays.fill(a, val);
- }
-
- public static void fill(boolean[] a, int fromIndex, int toIndex,
- boolean val) {
- java.util.Arrays.fill(a, fromIndex, toIndex, val);
- }
-
- public static void fill(double[] a, double val) {
- java.util.Arrays.fill(a, val);
- }
-
- public static void fill(double[] a, int fromIndex, int toIndex,double val) {
- java.util.Arrays.fill(a, fromIndex, toIndex, val);
- }
-
- public static void fill(float[] a, float val) {
- java.util.Arrays.fill(a, val);
- }
-
- public static void fill(float[] a, int fromIndex, int toIndex, float val) {
- java.util.Arrays.fill(a, fromIndex, toIndex, val);
- }
-
- public static void fill(Object[] a, Object val) {
- java.util.Arrays.fill(a, val);
- }
-
- public static void fill(Object[] a, int fromIndex, int toIndex, Object val) {
- java.util.Arrays.fill(a, fromIndex, toIndex, val);
- }
-
-
- // Cloning
-
- /**
- * @since 1.6
- */
- public static Object[] copyOf(Object[] original, int newLength) {
- return copyOf(original, newLength, original.getClass());
- }
-
- /**
- * @since 1.6
- */
- public static Object[] copyOf(Object[] original, int newLength, Class newType) {
- Object[] arr = (newType == Object[].class) ? new Object[newLength] :
- (Object[])Array.newInstance(newType.getComponentType(), newLength);
- int len = (original.length < newLength ? original.length : newLength);
- System.arraycopy(original, 0, arr, 0, len);
- return arr;
- }
-
- /**
- * @since 1.6
- */
- public static byte[] copyOf(byte[] original, int newLength) {
- byte[] arr = new byte[newLength];
- int len = (original.length < newLength ? original.length : newLength);
- System.arraycopy(original, 0, arr, 0, len);
- return arr;
- }
-
- /**
- * @since 1.6
- */
- public static short[] copyOf(short[] original, int newLength) {
- short[] arr = new short[newLength];
- int len = (original.length < newLength ? original.length : newLength);
- System.arraycopy(original, 0, arr, 0, len);
- return arr;
- }
-
- /**
- * @since 1.6
- */
- public static int[] copyOf(int[] original, int newLength) {
- int[] arr = new int[newLength];
- int len = (original.length < newLength ? original.length : newLength);
- System.arraycopy(original, 0, arr, 0, len);
- return arr;
- }
-
- /**
- * @since 1.6
- */
- public static long[] copyOf(long[] original, int newLength) {
- long[] arr = new long[newLength];
- int len = (original.length < newLength ? original.length : newLength);
- System.arraycopy(original, 0, arr, 0, len);
- return arr;
- }
-
- /**
- * @since 1.6
- */
- public static char[] copyOf(char[] original, int newLength) {
- char[] arr = new char[newLength];
- int len = (original.length < newLength ? original.length : newLength);
- System.arraycopy(original, 0, arr, 0, len);
- return arr;
- }
-
- /**
- * @since 1.6
- */
- public static float[] copyOf(float[] original, int newLength) {
- float[] arr = new float[newLength];
- int len = (original.length < newLength ? original.length : newLength);
- System.arraycopy(original, 0, arr, 0, len);
- return arr;
- }
-
- /**
- * @since 1.6
- */
- public static double[] copyOf(double[] original, int newLength) {
- double[] arr = new double[newLength];
- int len = (original.length < newLength ? original.length : newLength);
- System.arraycopy(original, 0, arr, 0, len);
- return arr;
- }
-
- /**
- * @since 1.6
- */
- public static boolean[] copyOf(boolean[] original, int newLength) {
- boolean[] arr = new boolean[newLength];
- int len = (original.length < newLength ? original.length : newLength);
- System.arraycopy(original, 0, arr, 0, len);
- return arr;
- }
-
- /**
- * @since 1.6
- */
- public static Object[] copyOfRange(Object[] original, int from, int to) {
- return copyOfRange(original, from, to, original.getClass());
- }
-
- /**
- * @since 1.6
- */
- public static Object[] copyOfRange(Object[] original, int from, int to, Class newType) {
- int newLength = to - from;
- if (newLength < 0) throw new IllegalArgumentException(from + " > " + to);
- Object[] arr = (newType == Object[].class) ? new Object[newLength] :
- (Object[])Array.newInstance(newType.getComponentType(), newLength);
- int ceil = original.length-from;
- int len = (ceil < newLength) ? ceil : newLength;
- System.arraycopy(original, from, arr, 0, len);
- return arr;
- }
-
- /**
- * @since 1.6
- */
- public static byte[] copyOfRange(byte[] original, int from, int to) {
- int newLength = to - from;
- if (newLength < 0) throw new IllegalArgumentException(from + " > " + to);
- byte[] arr = new byte[newLength];
- int ceil = original.length-from;
- int len = (ceil < newLength) ? ceil : newLength;
- System.arraycopy(original, from, arr, 0, len);
- return arr;
- }
-
- /**
- * @since 1.6
- */
- public static short[] copyOfRange(short[] original, int from, int to) {
- int newLength = to - from;
- if (newLength < 0) throw new IllegalArgumentException(from + " > " + to);
- short[] arr = new short[newLength];
- int ceil = original.length-from;
- int len = (ceil < newLength) ? ceil : newLength;
- System.arraycopy(original, from, arr, 0, len);
- return arr;
- }
-
- /**
- * @since 1.6
- */
- public static int[] copyOfRange(int[] original, int from, int to) {
- int newLength = to - from;
- if (newLength < 0) throw new IllegalArgumentException(from + " > " + to);
- int[] arr = new int[newLength];
- int ceil = original.length-from;
- int len = (ceil < newLength) ? ceil : newLength;
- System.arraycopy(original, from, arr, 0, len);
- return arr;
- }
-
- /**
- * @since 1.6
- */
- public static long[] copyOfRange(long[] original, int from, int to) {
- int newLength = to - from;
- if (newLength < 0) throw new IllegalArgumentException(from + " > " + to);
- long[] arr = new long[newLength];
- int ceil = original.length-from;
- int len = (ceil < newLength) ? ceil : newLength;
- System.arraycopy(original, from, arr, 0, len);
- return arr;
- }
-
- /**
- * @since 1.6
- */
- public static char[] copyOfRange(char[] original, int from, int to) {
- int newLength = to - from;
- if (newLength < 0) throw new IllegalArgumentException(from + " > " + to);
- char[] arr = new char[newLength];
- int ceil = original.length-from;
- int len = (ceil < newLength) ? ceil : newLength;
- System.arraycopy(original, from, arr, 0, len);
- return arr;
- }
-
- /**
- * @since 1.6
- */
- public static float[] copyOfRange(float[] original, int from, int to) {
- int newLength = to - from;
- if (newLength < 0) throw new IllegalArgumentException(from + " > " + to);
- float[] arr = new float[newLength];
- int ceil = original.length-from;
- int len = (ceil < newLength) ? ceil : newLength;
- System.arraycopy(original, from, arr, 0, len);
- return arr;
- }
-
- /**
- * @since 1.6
- */
- public static double[] copyOfRange(double[] original, int from, int to) {
- int newLength = to - from;
- if (newLength < 0) throw new IllegalArgumentException(from + " > " + to);
- double[] arr = new double[newLength];
- int ceil = original.length-from;
- int len = (ceil < newLength) ? ceil : newLength;
- System.arraycopy(original, from, arr, 0, len);
- return arr;
- }
-
- /**
- * @since 1.6
- */
- public static boolean[] copyOfRange(boolean[] original, int from, int to) {
- int newLength = to - from;
- if (newLength < 0) throw new IllegalArgumentException(from + " > " + to);
- boolean[] arr = new boolean[newLength];
- int ceil = original.length-from;
- int len = (ceil < newLength) ? ceil : newLength;
- System.arraycopy(original, from, arr, 0, len);
- return arr;
- }
-
-
- public static List asList(Object[] a) {
- return java.util.Arrays.asList(a);
- }
-
- /**
- * @since 1.5
- */
- public static int hashCode(long a[]) {
- if (a == null) return 0;
- int hash = 1;
- for (int i=0; i<a.length; i++) {
- long e = a[i];
- hash = 31*hash + (int)(e ^ (e >>> 32));
- }
- return hash;
- }
-
- /**
- * @since 1.5
- */
- public static int hashCode(int a[]) {
- if (a == null) return 0;
- int hash = 1;
- for (int i=0; i<a.length; i++) {
- hash = 31*hash + a[i];
- }
- return hash;
- }
-
- /**
- * @since 1.5
- */
- public static int hashCode(short a[]) {
- if (a == null) return 0;
- int hash = 1;
- for (int i=0; i<a.length; i++) {
- hash = 31*hash + a[i];
- }
- return hash;
- }
-
- /**
- * @since 1.5
- */
- public static int hashCode(char a[]) {
- if (a == null) return 0;
- int hash = 1;
- for (int i=0; i<a.length; i++) {
- hash = 31*hash + a[i];
- }
- return hash;
- }
-
- /**
- * @since 1.5
- */
- public static int hashCode(byte a[]) {
- if (a == null) return 0;
- int hash = 1;
- for (int i=0; i<a.length; i++) {
- hash = 31*hash + a[i];
- }
- return hash;
- }
-
- /**
- * @since 1.5
- */
- public static int hashCode(boolean a[]) {
- if (a == null) return 0;
- int hash = 1;
- for (int i=0; i<a.length; i++) {
- hash = 31*hash + (a[i] ? 1231 : 1237);
- }
- return hash;
- }
-
- /**
- * @since 1.5
- */
- public static int hashCode(float a[]) {
- if (a == null) return 0;
- int hash = 1;
- for (int i=0; i<a.length; i++) {
- hash = 31*hash + Float.floatToIntBits(a[i]);
- }
- return hash;
- }
-
- /**
- * @since 1.5
- */
- public static int hashCode(double a[]) {
- if (a == null) return 0;
- int hash = 1;
- for (int i=0; i<a.length; i++) {
- long e = Double.doubleToLongBits(a[i]);
- hash = 31*hash + (int)(e ^ (e >>> 32));
- }
- return hash;
- }
-
- /**
- * @since 1.5
- */
- public static int hashCode(Object a[]) {
- if (a == null) return 0;
- int hash = 1;
- for (int i=0; i<a.length; i++) {
- Object e = a[i];
- hash = 31*hash + (e == null ? 0 : e.hashCode());
- }
- return hash;
- }
-
- /**
- * @since 1.5
- */
- public static int deepHashCode(Object a[]) {
- if (a == null) return 0;
- int hash = 1;
- for (int i=0; i<a.length; i++) {
- Object e = a[i];
- hash = 31*hash +
- (e instanceof Object[] ? deepHashCode((Object[])e) :
- (e instanceof byte[] ? hashCode((byte[])e) :
- (e instanceof short[] ? hashCode((short[])e) :
- (e instanceof int[] ? hashCode((int[])e) :
- (e instanceof long[] ? hashCode((long[])e) :
- (e instanceof char[] ? hashCode((char[])e) :
- (e instanceof boolean[] ? hashCode((boolean[])e) :
- (e instanceof float[] ? hashCode((float[])e) :
- (e instanceof double[] ? hashCode((double[])e) :
- (e != null ? e.hashCode() : 0))))))))));
- }
- return hash;
-
- }
-
- /**
- * @since 1.5
- */
- public static boolean deepEquals(Object[] a1, Object[] a2) {
- if (a1 == a2) return true;
- if (a1 == null || a2==null) return false;
- int len = a1.length;
- if (len != a2.length) return false;
- for (int i = 0; i < len; i++) {
- Object e1 = a1[i];
- Object e2 = a2[i];
- if (e1 == e2) continue;
- if (e1 == null) return false;
- boolean eq =
- (e1.getClass() != e2.getClass() || e1.getClass().isArray()) ?
- e1.equals(e2) :
- (e1 instanceof Object[] && e2 instanceof Object[]) ?
- deepEquals((Object[])e1, (Object[])e2) :
- (e1 instanceof byte[] && e2 instanceof byte[]) ?
- equals((byte[])e1, (byte[])e2) :
- (e1 instanceof short[] && e2 instanceof short[]) ?
- equals((short[])e1, (short[])e2) :
- (e1 instanceof int[] && e2 instanceof int[]) ?
- equals((int[])e1, (int[])e2) :
- (e1 instanceof long[] && e2 instanceof long[]) ?
- equals((long[])e1, (long[])e2) :
- (e1 instanceof char[] && e2 instanceof char[]) ?
- equals((char[])e1, (char[])e2) :
- (e1 instanceof boolean[] && e2 instanceof boolean[]) ?
- equals((boolean[])e1, (boolean[])e2) :
- (e1 instanceof float[] && e2 instanceof float[]) ?
- equals((float[])e1, (float[])e2) :
- (e1 instanceof double[] && e2 instanceof double[]) ?
- equals((double[])e1, (double[])e2) :
- e1.equals(e2);
-
- if (!eq) return false;
- }
- return true;
- }
-
- /**
- * @since 1.5
- */
- public static String toString(long[] a) {
- if (a == null) return "null";
- if (a.length == 0) return "[]";
- StringBuffer buf = new StringBuffer();
- buf.append('[').append(a[0]);
- for (int i=1; i<a.length; i++) buf.append(", ").append(a[i]);
- buf.append(']');
- return buf.toString();
- }
-
- /**
- * @since 1.5
- */
- public static String toString(int[] a) {
- if (a == null) return "null";
- if (a.length == 0) return "[]";
- StringBuffer buf = new StringBuffer();
- buf.append('[').append(a[0]);
- for (int i=1; i<a.length; i++) buf.append(", ").append(a[i]);
- buf.append(']');
- return buf.toString();
- }
-
- /**
- * @since 1.5
- */
- public static String toString(short[] a) {
- if (a == null) return "null";
- if (a.length == 0) return "[]";
- StringBuffer buf = new StringBuffer();
- buf.append('[').append(a[0]);
- for (int i=1; i<a.length; i++) buf.append(", ").append(a[i]);
- buf.append(']');
- return buf.toString();
- }
-
- /**
- * @since 1.5
- */
- public static String toString(char[] a) {
- if (a == null) return "null";
- if (a.length == 0) return "[]";
- StringBuffer buf = new StringBuffer();
- buf.append('[').append(a[0]);
- for (int i=1; i<a.length; i++) buf.append(", ").append(a[i]);
- buf.append(']');
- return buf.toString();
- }
-
- /**
- * @since 1.5
- */
- public static String toString(byte[] a) {
- if (a == null) return "null";
- if (a.length == 0) return "[]";
- StringBuffer buf = new StringBuffer();
- buf.append('[').append(a[0]);
- for (int i=1; i<a.length; i++) buf.append(", ").append(a[i]);
- buf.append(']');
- return buf.toString();
- }
-
- /**
- * @since 1.5
- */
- public static String toString(boolean[] a) {
- if (a == null) return "null";
- if (a.length == 0) return "[]";
- StringBuffer buf = new StringBuffer();
- buf.append('[').append(a[0]);
- for (int i=1; i<a.length; i++) buf.append(", ").append(a[i]);
- buf.append(']');
- return buf.toString();
- }
-
- /**
- * @since 1.5
- */
- public static String toString(float[] a) {
- if (a == null) return "null";
- if (a.length == 0) return "[]";
- StringBuffer buf = new StringBuffer();
- buf.append('[').append(a[0]);
- for (int i=1; i<a.length; i++) buf.append(", ").append(a[i]);
- buf.append(']');
- return buf.toString();
- }
-
- /**
- * @since 1.5
- */
- public static String toString(double[] a) {
- if (a == null) return "null";
- if (a.length == 0) return "[]";
- StringBuffer buf = new StringBuffer();
- buf.append('[').append(a[0]);
- for (int i=1; i<a.length; i++) buf.append(", ").append(a[i]);
- buf.append(']');
- return buf.toString();
- }
-
- /**
- * @since 1.5
- */
- public static String toString(Object[] a) {
- if (a == null) return "null";
- if (a.length == 0) return "[]";
- StringBuffer buf = new StringBuffer();
- buf.append('[').append(a[0]);
- for (int i=1; i<a.length; i++) buf.append(", ").append(a[i]);
- buf.append(']');
- return buf.toString();
- }
-
- /**
- * @since 1.5
- */
- public static String deepToString(Object[] a) {
- if (a == null) return "null";
- StringBuffer buf = new StringBuffer();
- deepToString(a, buf, new ArrayList());
- return buf.toString();
- }
-
- private static void deepToString(Object[] a, StringBuffer buf, List seen) {
- seen.add(a);
- buf.append('[');
- for (int i = 0; i < a.length; i++) {
- if (i>0) buf.append(", ");
- Object e = a[i];
- if (e == null) {
- buf.append("null");
- }
- else if (!e.getClass().isArray()) {
- buf.append(e.toString());
- }
- else if (e instanceof Object[]) {
- if (seen.contains(e)) buf.append("[...]");
- else deepToString((Object[])e, buf, seen);
- }
- else {
- // primitive arr
- buf.append(
- (e instanceof byte[]) ? toString( (byte[]) e) :
- (e instanceof short[]) ? toString( (short[]) e) :
- (e instanceof int[]) ? toString( (int[]) e) :
- (e instanceof long[]) ? toString( (long[]) e) :
- (e instanceof char[]) ? toString( (char[]) e) :
- (e instanceof boolean[]) ? toString( (boolean[]) e) :
- (e instanceof float[]) ? toString( (float[]) e) :
- (e instanceof double[]) ? toString( (double[]) e) : "");
- }
- }
- buf.append(']');
- seen.remove(seen.size()-1);
- }
-}
diff --git a/src/actors/scala/actors/threadpool/AtomicInteger.java b/src/actors/scala/actors/threadpool/AtomicInteger.java
deleted file mode 100644
index eedb84512a..0000000000
--- a/src/actors/scala/actors/threadpool/AtomicInteger.java
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
- */
-
-package scala.actors.threadpool;
-
-/**
- * An {@code int} value that may be updated atomically. See the
- * {@link edu.emory.mathcs.backport.java.util.concurrent.atomic} package specification for
- * description of the properties of atomic variables. An
- * {@code AtomicInteger} is used in applications such as atomically
- * incremented counters, and cannot be used as a replacement for an
- * {@link java.lang.Integer}. However, this class does extend
- * {@code Number} to allow uniform access by tools and utilities that
- * deal with numerically-based classes.
- *
- * @since 1.5
- * @author Doug Lea
-*/
-public class AtomicInteger extends Number implements java.io.Serializable {
- private static final long serialVersionUID = 6214790243416807050L;
-
- private volatile int value;
-
- /**
- * Creates a new AtomicInteger with the given initial value.
- *
- * @param initialValue the initial value
- */
- public AtomicInteger(int initialValue) {
- value = initialValue;
- }
-
- /**
- * Creates a new AtomicInteger with initial value {@code 0}.
- */
- public AtomicInteger() {
- }
-
- /**
- * Gets the current value.
- *
- * @return the current value
- */
- public final int get() {
- return value;
- }
-
- /**
- * Sets to the given value.
- *
- * @param newValue the new value
- */
- public final synchronized void set(int newValue) {
- value = newValue;
- }
-
- /**
- * Eventually sets to the given value.
- *
- * @param newValue the new value
- * @since 1.6
- */
- public final synchronized void lazySet(int newValue) {
- value = newValue;
- }
-
- /**
- * Atomically sets to the given value and returns the old value.
- *
- * @param newValue the new value
- * @return the previous value
- */
- public final synchronized int getAndSet(int newValue) {
- int old = value;
- value = newValue;
- return old;
- }
-
- /**
- * Atomically sets the value to the given updated value
- * if the current value {@code ==} the expected value.
- *
- * @param expect the expected value
- * @param update the new value
- * @return true if successful. False return indicates that
- * the actual value was not equal to the expected value.
- */
- public final synchronized boolean compareAndSet(int expect, int update) {
- if (value == expect) {
- value = update;
- return true;
- }
- else {
- return false;
- }
- }
-
- /**
- * Atomically sets the value to the given updated value
- * if the current value {@code ==} the expected value.
- *
- * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
- * and does not provide ordering guarantees, so is only rarely an
- * appropriate alternative to {@code compareAndSet}.
- *
- * @param expect the expected value
- * @param update the new value
- * @return true if successful.
- */
- public final synchronized boolean weakCompareAndSet(int expect, int update) {
- if (value == expect) {
- value = update;
- return true;
- }
- else {
- return false;
- }
- }
-
-
- /**
- * Atomically increments by one the current value.
- *
- * @return the previous value
- */
- public final synchronized int getAndIncrement() {
- return value++;
- }
-
-
- /**
- * Atomically decrements by one the current value.
- *
- * @return the previous value
- */
- public final synchronized int getAndDecrement() {
- return value--;
- }
-
-
- /**
- * Atomically adds the given value to the current value.
- *
- * @param delta the value to add
- * @return the previous value
- */
- public final synchronized int getAndAdd(int delta) {
- int old = value;
- value += delta;
- return old;
- }
-
- /**
- * Atomically increments by one the current value.
- *
- * @return the updated value
- */
- public final synchronized int incrementAndGet() {
- return ++value;
- }
-
- /**
- * Atomically decrements by one the current value.
- *
- * @return the updated value
- */
- public final synchronized int decrementAndGet() {
- return --value;
- }
-
-
- /**
- * Atomically adds the given value to the current value.
- *
- * @param delta the value to add
- * @return the updated value
- */
- public final synchronized int addAndGet(int delta) {
- return value += delta;
- }
-
- /**
- * Returns the String representation of the current value.
- * @return the String representation of the current value.
- */
- public String toString() {
- return Integer.toString(get());
- }
-
-
- public int intValue() {
- return get();
- }
-
- public long longValue() {
- return (long)get();
- }
-
- public float floatValue() {
- return (float)get();
- }
-
- public double doubleValue() {
- return (double)get();
- }
-
-}
diff --git a/src/actors/scala/actors/threadpool/BlockingQueue.java b/src/actors/scala/actors/threadpool/BlockingQueue.java
deleted file mode 100644
index 4b8c201b85..0000000000
--- a/src/actors/scala/actors/threadpool/BlockingQueue.java
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
- */
-
-package scala.actors.threadpool;
-
-import java.util.Collection;
-import java.util.Queue;
-
-/**
- * A {@link java.util.Queue} that additionally supports operations
- * that wait for the queue to become non-empty when retrieving an
- * element, and wait for space to become available in the queue when
- * storing an element.
- *
- * <p><tt>BlockingQueue</tt> methods come in four forms, with different ways
- * of handling operations that cannot be satisfied immediately, but may be
- * satisfied at some point in the future:
- * one throws an exception, the second returns a special value (either
- * <tt>null</tt> or <tt>false</tt>, depending on the operation), the third
- * blocks the current thread indefinitely until the operation can succeed,
- * and the fourth blocks for only a given maximum time limit before giving
- * up. These methods are summarized in the following table:
- *
- * <p>
- * <table BORDER CELLPADDING=3 CELLSPACING=1>
- * <tr>
- * <td></td>
- * <td ALIGN=CENTER><em>Throws exception</em></td>
- * <td ALIGN=CENTER><em>Special value</em></td>
- * <td ALIGN=CENTER><em>Blocks</em></td>
- * <td ALIGN=CENTER><em>Times out</em></td>
- * </tr>
- * <tr>
- * <td><b>Insert</b></td>
- * <td>{@link #add add(e)}</td>
- * <td>{@link #offer offer(e)}</td>
- * <td>{@link #put put(e)}</td>
- * <td>{@link #offer(Object, long, TimeUnit) offer(e, time, unit)}</td>
- * </tr>
- * <tr>
- * <td><b>Remove</b></td>
- * <td>{@link #remove remove()}</td>
- * <td>{@link #poll poll()}</td>
- * <td>{@link #take take()}</td>
- * <td>{@link #poll(long, TimeUnit) poll(time, unit)}</td>
- * </tr>
- * <tr>
- * <td><b>Examine</b></td>
- * <td>{@link #element element()}</td>
- * <td>{@link #peek peek()}</td>
- * <td><em>not applicable</em></td>
- * <td><em>not applicable</em></td>
- * </tr>
- * </table>
- *
- * <p>A <tt>BlockingQueue</tt> does not accept <tt>null</tt> elements.
- * Implementations throw <tt>NullPointerException</tt> on attempts
- * to <tt>add</tt>, <tt>put</tt> or <tt>offer</tt> a <tt>null</tt>. A
- * <tt>null</tt> is used as a sentinel value to indicate failure of
- * <tt>poll</tt> operations.
- *
- * <p>A <tt>BlockingQueue</tt> may be capacity bounded. At any given
- * time it may have a <tt>remainingCapacity</tt> beyond which no
- * additional elements can be <tt>put</tt> without blocking.
- * A <tt>BlockingQueue</tt> without any intrinsic capacity constraints always
- * reports a remaining capacity of <tt>Integer.MAX_VALUE</tt>.
- *
- * <p> <tt>BlockingQueue</tt> implementations are designed to be used
- * primarily for producer-consumer queues, but additionally support
- * the {@link java.util.Collection} interface. So, for example, it is
- * possible to remove an arbitrary element from a queue using
- * <tt>remove(x)</tt>. However, such operations are in general
- * <em>not</em> performed very efficiently, and are intended for only
- * occasional use, such as when a queued message is cancelled.
- *
- * <p> <tt>BlockingQueue</tt> implementations are thread-safe. All
- * queuing methods achieve their effects atomically using internal
- * locks or other forms of concurrency control. However, the
- * <em>bulk</em> Collection operations <tt>addAll</tt>,
- * <tt>containsAll</tt>, <tt>retainAll</tt> and <tt>removeAll</tt> are
- * <em>not</em> necessarily performed atomically unless specified
- * otherwise in an implementation. So it is possible, for example, for
- * <tt>addAll(c)</tt> to fail (throwing an exception) after adding
- * only some of the elements in <tt>c</tt>.
- *
- * <p>A <tt>BlockingQueue</tt> does <em>not</em> intrinsically support
- * any kind of &quot;close&quot; or &quot;shutdown&quot; operation to
- * indicate that no more items will be added. The needs and usage of
- * such features tend to be implementation-dependent. For example, a
- * common tactic is for producers to insert special
- * <em>end-of-stream</em> or <em>poison</em> objects, that are
- * interpreted accordingly when taken by consumers.
- *
- * <p>
- * Usage example, based on a typical producer-consumer scenario.
- * Note that a <tt>BlockingQueue</tt> can safely be used with multiple
- * producers and multiple consumers.
- * <pre>
- * class Producer implements Runnable {
- * private final BlockingQueue queue;
- * Producer(BlockingQueue q) { queue = q; }
- * public void run() {
- * try {
- * while (true) { queue.put(produce()); }
- * } catch (InterruptedException ex) { ... handle ...}
- * }
- * Object produce() { ... }
- * }
- *
- * class Consumer implements Runnable {
- * private final BlockingQueue queue;
- * Consumer(BlockingQueue q) { queue = q; }
- * public void run() {
- * try {
- * while (true) { consume(queue.take()); }
- * } catch (InterruptedException ex) { ... handle ...}
- * }
- * void consume(Object x) { ... }
- * }
- *
- * class Setup {
- * void main() {
- * BlockingQueue q = new SomeQueueImplementation();
- * Producer p = new Producer(q);
- * Consumer c1 = new Consumer(q);
- * Consumer c2 = new Consumer(q);
- * new Thread(p).start();
- * new Thread(c1).start();
- * new Thread(c2).start();
- * }
- * }
- * </pre>
- *
- * <p>Memory consistency effects: As with other concurrent
- * collections, actions in a thread prior to placing an object into a
- * {@code BlockingQueue}
- * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
- * actions subsequent to the access or removal of that element from
- * the {@code BlockingQueue} in another thread.
- *
- * <p>This interface is a member of the
- * <a href="{@docRoot}/../technotes/guides/collections/index.html">
- * Java Collections Framework</a>.
- *
- * @since 1.5
- * @author Doug Lea
- * @param <E> the type of elements held in this collection
- */
-public interface BlockingQueue<E> extends java.util.Queue<E> {
- /**
- * Inserts the specified element into this queue if it is possible to do
- * so immediately without violating capacity restrictions, returning
- * <tt>true</tt> upon success and throwing an
- * <tt>IllegalStateException</tt> if no space is currently available.
- * When using a capacity-restricted queue, it is generally preferable to
- * use {@link #offer(Object) offer}.
- *
- * @param e the element to add
- * @return <tt>true</tt> (as specified by {@link Collection#add})
- * @throws IllegalStateException if the element cannot be added at this
- * time due to capacity restrictions
- * @throws ClassCastException if the class of the specified element
- * prevents it from being added to this queue
- * @throws NullPointerException if the specified element is null
- * @throws IllegalArgumentException if some property of the specified
- * element prevents it from being added to this queue
- */
- boolean add(E e);
-
- /**
- * Inserts the specified element into this queue if it is possible to do
- * so immediately without violating capacity restrictions, returning
- * <tt>true</tt> upon success and <tt>false</tt> if no space is currently
- * available. When using a capacity-restricted queue, this method is
- * generally preferable to {@link #add}, which can fail to insert an
- * element only by throwing an exception.
- *
- * @param e the element to add
- * @return <tt>true</tt> if the element was added to this queue, else
- * <tt>false</tt>
- * @throws ClassCastException if the class of the specified element
- * prevents it from being added to this queue
- * @throws NullPointerException if the specified element is null
- * @throws IllegalArgumentException if some property of the specified
- * element prevents it from being added to this queue
- */
- boolean offer(E e);
-
- /**
- * Inserts the specified element into this queue, waiting if necessary
- * for space to become available.
- *
- * @param e the element to add
- * @throws InterruptedException if interrupted while waiting
- * @throws ClassCastException if the class of the specified element
- * prevents it from being added to this queue
- * @throws NullPointerException if the specified element is null
- * @throws IllegalArgumentException if some property of the specified
- * element prevents it from being added to this queue
- */
- void put(E e) throws InterruptedException;
-
- /**
- * Inserts the specified element into this queue, waiting up to the
- * specified wait time if necessary for space to become available.
- *
- * @param e the element to add
- * @param timeout how long to wait before giving up, in units of
- * <tt>unit</tt>
- * @param unit a <tt>TimeUnit</tt> determining how to interpret the
- * <tt>timeout</tt> parameter
- * @return <tt>true</tt> if successful, or <tt>false</tt> if
- * the specified waiting time elapses before space is available
- * @throws InterruptedException if interrupted while waiting
- * @throws ClassCastException if the class of the specified element
- * prevents it from being added to this queue
- * @throws NullPointerException if the specified element is null
- * @throws IllegalArgumentException if some property of the specified
- * element prevents it from being added to this queue
- */
- boolean offer(E e, long timeout, TimeUnit unit)
- throws InterruptedException;
-
- /**
- * Retrieves and removes the head of this queue, waiting if necessary
- * until an element becomes available.
- *
- * @return the head of this queue
- * @throws InterruptedException if interrupted while waiting
- */
- E take() throws InterruptedException;
-
- /**
- * Retrieves and removes the head of this queue, waiting up to the
- * specified wait time if necessary for an element to become available.
- *
- * @param timeout how long to wait before giving up, in units of
- * <tt>unit</tt>
- * @param unit a <tt>TimeUnit</tt> determining how to interpret the
- * <tt>timeout</tt> parameter
- * @return the head of this queue, or <tt>null</tt> if the
- * specified waiting time elapses before an element is available
- * @throws InterruptedException if interrupted while waiting
- */
- E poll(long timeout, TimeUnit unit)
- throws InterruptedException;
-
- /**
- * Returns the number of additional elements that this queue can ideally
- * (in the absence of memory or resource constraints) accept without
- * blocking, or <tt>Integer.MAX_VALUE</tt> if there is no intrinsic
- * limit.
- *
- * <p>Note that you <em>cannot</em> always tell if an attempt to insert
- * an element will succeed by inspecting <tt>remainingCapacity</tt>
- * because it may be the case that another thread is about to
- * insert or remove an element.
- *
- * @return the remaining capacity
- */
- int remainingCapacity();
-
- /**
- * Removes a single instance of the specified element from this queue,
- * if it is present. More formally, removes an element <tt>e</tt> such
- * that <tt>o.equals(e)</tt>, if this queue contains one or more such
- * elements.
- * Returns <tt>true</tt> if this queue contained the specified element
- * (or equivalently, if this queue changed as a result of the call).
- *
- * @param o element to be removed from this queue, if present
- * @return <tt>true</tt> if this queue changed as a result of the call
- * @throws ClassCastException if the class of the specified element
- * is incompatible with this queue (optional)
- * @throws NullPointerException if the specified element is null (optional)
- */
- boolean remove(Object o);
-
- /**
- * Returns <tt>true</tt> if this queue contains the specified element.
- * More formally, returns <tt>true</tt> if and only if this queue contains
- * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>.
- *
- * @param o object to be checked for containment in this queue
- * @return <tt>true</tt> if this queue contains the specified element
- * @throws ClassCastException if the class of the specified element
- * is incompatible with this queue (optional)
- * @throws NullPointerException if the specified element is null (optional)
- */
- public boolean contains(Object o);
-
- /**
- * Removes all available elements from this queue and adds them
- * to the given collection. This operation may be more
- * efficient than repeatedly polling this queue. A failure
- * encountered while attempting to add elements to
- * collection <tt>c</tt> may result in elements being in neither,
- * either or both collections when the associated exception is
- * thrown. Attempts to drain a queue to itself result in
- * <tt>IllegalArgumentException</tt>. Further, the behavior of
- * this operation is undefined if the specified collection is
- * modified while the operation is in progress.
- *
- * @param c the collection to transfer elements into
- * @return the number of elements transferred
- * @throws UnsupportedOperationException if addition of elements
- * is not supported by the specified collection
- * @throws ClassCastException if the class of an element of this queue
- * prevents it from being added to the specified collection
- * @throws NullPointerException if the specified collection is null
- * @throws IllegalArgumentException if the specified collection is this
- * queue, or some property of an element of this queue prevents
- * it from being added to the specified collection
- */
- int drainTo(Collection<? super E> c);
-
- /**
- * Removes at most the given number of available elements from
- * this queue and adds them to the given collection. A failure
- * encountered while attempting to add elements to
- * collection <tt>c</tt> may result in elements being in neither,
- * either or both collections when the associated exception is
- * thrown. Attempts to drain a queue to itself result in
- * <tt>IllegalArgumentException</tt>. Further, the behavior of
- * this operation is undefined if the specified collection is
- * modified while the operation is in progress.
- *
- * @param c the collection to transfer elements into
- * @param maxElements the maximum number of elements to transfer
- * @return the number of elements transferred
- * @throws UnsupportedOperationException if addition of elements
- * is not supported by the specified collection
- * @throws ClassCastException if the class of an element of this queue
- * prevents it from being added to the specified collection
- * @throws NullPointerException if the specified collection is null
- * @throws IllegalArgumentException if the specified collection is this
- * queue, or some property of an element of this queue prevents
- * it from being added to the specified collection
- */
- int drainTo(Collection<? super E> c, int maxElements);
-}
diff --git a/src/actors/scala/actors/threadpool/Callable.java b/src/actors/scala/actors/threadpool/Callable.java
deleted file mode 100644
index f1b200c022..0000000000
--- a/src/actors/scala/actors/threadpool/Callable.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
- */
-
-package scala.actors.threadpool;
-
-/**
- * A task that returns a result and may throw an exception.
- * Implementors define a single method with no arguments called
- * <tt>call</tt>.
- *
- * <p>The <tt>Callable</tt> interface is similar to {@link
- * java.lang.Runnable}, in that both are designed for classes whose
- * instances are potentially executed by another thread. A
- * <tt>Runnable</tt>, however, does not return a result and cannot
- * throw a checked exception.
- *
- * <p> The {@link Executors} class contains utility methods to
- * convert from other common forms to <tt>Callable</tt> classes.
- *
- * @see Executor
- * @since 1.5
- * @author Doug Lea
- */
-public interface Callable {
- /**
- * Computes a result, or throws an exception if unable to do so.
- *
- * @return computed result
- * @throws Exception if unable to compute a result
- */
- Object call() throws Exception;
-}
diff --git a/src/actors/scala/actors/threadpool/CancellationException.java b/src/actors/scala/actors/threadpool/CancellationException.java
deleted file mode 100644
index c2163b83c7..0000000000
--- a/src/actors/scala/actors/threadpool/CancellationException.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
- */
-
-package scala.actors.threadpool;
-
-/**
- * Exception indicating that the result of a value-producing task,
- * such as a {@link FutureTask}, cannot be retrieved because the task
- * was cancelled.
- *
- * @since 1.5
- * @author Doug Lea
- */
-public class CancellationException extends IllegalStateException {
- private static final long serialVersionUID = -9202173006928992231L;
-
- /**
- * Constructs a <tt>CancellationException</tt> with no detail message.
- */
- public CancellationException() {}
-
- /**
- * Constructs a <tt>CancellationException</tt> with the specified detail
- * message.
- *
- * @param message the detail message
- */
- public CancellationException(String message) {
- super(message);
- }
-}
diff --git a/src/actors/scala/actors/threadpool/CompletionService.java b/src/actors/scala/actors/threadpool/CompletionService.java
deleted file mode 100644
index 219ab7affa..0000000000
--- a/src/actors/scala/actors/threadpool/CompletionService.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
- */
-
-package scala.actors.threadpool;
-
-/**
- * A service that decouples the production of new asynchronous tasks
- * from the consumption of the results of completed tasks. Producers
- * <tt>submit</tt> tasks for execution. Consumers <tt>take</tt>
- * completed tasks and process their results in the order they
- * complete. A <tt>CompletionService</tt> can for example be used to
- * manage asynchronous IO, in which tasks that perform reads are
- * submitted in one part of a program or system, and then acted upon
- * in a different part of the program when the reads complete,
- * possibly in a different order than they were requested.
- *
- * <p>Typically, a <tt>CompletionService</tt> relies on a separate
- * {@link Executor} to actually execute the tasks, in which case the
- * <tt>CompletionService</tt> only manages an internal completion
- * queue. The {@link ExecutorCompletionService} class provides an
- * implementation of this approach.
- *
- * <p>Memory consistency effects: Actions in a thread prior to
- * submitting a task to a {@code CompletionService}
- * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
- * actions taken by that task, which in turn <i>happen-before</i>
- * actions following a successful return from the corresponding {@code take()}.
- *
- */
-public interface CompletionService {
- /**
- * Submits a value-returning task for execution and returns a Future
- * representing the pending results of the task. Upon completion,
- * this task may be taken or polled.
- *
- * @param task the task to submit
- * @return a Future representing pending completion of the task
- * @throws RejectedExecutionException if the task cannot be
- * scheduled for execution
- * @throws NullPointerException if the task is null
- */
- Future submit(Callable task);
-
- /**
- * Submits a Runnable task for execution and returns a Future
- * representing that task. Upon completion, this task may be
- * taken or polled.
- *
- * @param task the task to submit
- * @param result the result to return upon successful completion
- * @return a Future representing pending completion of the task,
- * and whose <tt>get()</tt> method will return the given
- * result value upon completion
- * @throws RejectedExecutionException if the task cannot be
- * scheduled for execution
- * @throws NullPointerException if the task is null
- */
- Future submit(Runnable task, Object result);
-
- /**
- * Retrieves and removes the Future representing the next
- * completed task, waiting if none are yet present.
- *
- * @return the Future representing the next completed task
- * @throws InterruptedException if interrupted while waiting
- */
- Future take() throws InterruptedException;
-
-
- /**
- * Retrieves and removes the Future representing the next
- * completed task or <tt>null</tt> if none are present.
- *
- * @return the Future representing the next completed task, or
- * <tt>null</tt> if none are present
- */
- Future poll();
-
- /**
- * Retrieves and removes the Future representing the next
- * completed task, waiting if necessary up to the specified wait
- * time if none are yet present.
- *
- * @param timeout how long to wait before giving up, in units of
- * <tt>unit</tt>
- * @param unit a <tt>TimeUnit</tt> determining how to interpret the
- * <tt>timeout</tt> parameter
- * @return the Future representing the next completed task or
- * <tt>null</tt> if the specified waiting time elapses
- * before one is present
- * @throws InterruptedException if interrupted while waiting
- */
- Future poll(long timeout, TimeUnit unit) throws InterruptedException;
-}
diff --git a/src/actors/scala/actors/threadpool/ExecutionException.java b/src/actors/scala/actors/threadpool/ExecutionException.java
deleted file mode 100644
index 912f965acf..0000000000
--- a/src/actors/scala/actors/threadpool/ExecutionException.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
- */
-
-package scala.actors.threadpool;
-
-/**
- * Exception thrown when attempting to retrieve the result of a task
- * that aborted by throwing an exception. This exception can be
- * inspected using the {@link #getCause()} method.
- *
- * @see Future
- * @since 1.5
- * @author Doug Lea
- */
-public class ExecutionException extends Exception {
- private static final long serialVersionUID = 7830266012832686185L;
-
- /**
- * Constructs an <tt>ExecutionException</tt> with no detail message.
- * The cause is not initialized, and may subsequently be
- * initialized by a call to {@link #initCause(Throwable) initCause}.
- */
- protected ExecutionException() { }
-
- /**
- * Constructs an <tt>ExecutionException</tt> with the specified detail
- * message. The cause is not initialized, and may subsequently be
- * initialized by a call to {@link #initCause(Throwable) initCause}.
- *
- * @param message the detail message
- */
- protected ExecutionException(String message) {
- super(message);
- }
-
- /**
- * Constructs an <tt>ExecutionException</tt> with the specified detail
- * message and cause.
- *
- * @param message the detail message
- * @param cause the cause (which is saved for later retrieval by the
- * {@link #getCause()} method)
- */
- public ExecutionException(String message, Throwable cause) {
- super(message, cause);
- }
-
- /**
- * Constructs an <tt>ExecutionException</tt> with the specified cause.
- * The detail message is set to:
- * <pre>
- * (cause == null ? null : cause.toString())</pre>
- * (which typically contains the class and detail message of
- * <tt>cause</tt>).
- *
- * @param cause the cause (which is saved for later retrieval by the
- * {@link #getCause()} method)
- */
- public ExecutionException(Throwable cause) {
- super(cause);
- }
-}
diff --git a/src/actors/scala/actors/threadpool/Executor.java b/src/actors/scala/actors/threadpool/Executor.java
deleted file mode 100644
index e444e64dff..0000000000
--- a/src/actors/scala/actors/threadpool/Executor.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
- */
-
-package scala.actors.threadpool;
-
-/**
- * An object that executes submitted {@link Runnable} tasks. This
- * interface provides a way of decoupling task submission from the
- * mechanics of how each task will be run, including details of thread
- * use, scheduling, etc. An <tt>Executor</tt> is normally used
- * instead of explicitly creating threads. For example, rather than
- * invoking <tt>new Thread(new(RunnableTask())).start()</tt> for each
- * of a set of tasks, you might use:
- *
- * <pre>
- * Executor executor = <em>anExecutor</em>;
- * executor.execute(new RunnableTask1());
- * executor.execute(new RunnableTask2());
- * ...
- * </pre>
- *
- * However, the <tt>Executor</tt> interface does not strictly
- * require that execution be asynchronous. In the simplest case, an
- * executor can run the submitted task immediately in the caller's
- * thread:
- *
- * <pre>
- * class DirectExecutor implements Executor {
- * public void execute(Runnable r) {
- * r.run();
- * }
- * }</pre>
- *
- * More typically, tasks are executed in some thread other
- * than the caller's thread. The executor below spawns a new thread
- * for each task.
- *
- * <pre>
- * class ThreadPerTaskExecutor implements Executor {
- * public void execute(Runnable r) {
- * new Thread(r).start();
- * }
- * }</pre>
- *
- * Many <tt>Executor</tt> implementations impose some sort of
- * limitation on how and when tasks are scheduled. The executor below
- * serializes the submission of tasks to a second executor,
- * illustrating a composite executor.
- *
- * <pre>
- * class SerialExecutor implements Executor {
- * final Queue&lt;Runnable&gt; tasks = new ArrayDeque&lt;Runnable&gt;();
- * final Executor executor;
- * Runnable active;
- *
- * SerialExecutor(Executor executor) {
- * this.executor = executor;
- * }
- *
- * public synchronized void execute(final Runnable r) {
- * tasks.offer(new Runnable() {
- * public void run() {
- * try {
- * r.run();
- * } finally {
- * scheduleNext();
- * }
- * }
- * });
- * if (active == null) {
- * scheduleNext();
- * }
- * }
- *
- * protected synchronized void scheduleNext() {
- * if ((active = tasks.poll()) != null) {
- * executor.execute(active);
- * }
- * }
- * }</pre>
- *
- * The <tt>Executor</tt> implementations provided in this package
- * implement {@link ExecutorService}, which is a more extensive
- * interface. The {@link ThreadPoolExecutor} class provides an
- * extensible thread pool implementation. The {@link Executors} class
- * provides convenient factory methods for these Executors.
- *
- * <p>Memory consistency effects: Actions in a thread prior to
- * submitting a {@code Runnable} object to an {@code Executor}
- * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
- * its execution begins, perhaps in another thread.
- *
- * @since 1.5
- * @author Doug Lea
- */
-public interface Executor {
-
- /**
- * Executes the given command at some time in the future. The command
- * may execute in a new thread, in a pooled thread, or in the calling
- * thread, at the discretion of the <tt>Executor</tt> implementation.
- *
- * @param command the runnable task
- * @throws RejectedExecutionException if this task cannot be
- * accepted for execution.
- * @throws NullPointerException if command is null
- */
- void execute(Runnable command);
-}
diff --git a/src/actors/scala/actors/threadpool/ExecutorCompletionService.java b/src/actors/scala/actors/threadpool/ExecutorCompletionService.java
deleted file mode 100644
index 02e9bbe297..0000000000
--- a/src/actors/scala/actors/threadpool/ExecutorCompletionService.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
- */
-
-package scala.actors.threadpool;
-import scala.actors.threadpool.*; // for javadoc (till 6280605 is fixed)
-
-/**
- * A {@link CompletionService} that uses a supplied {@link Executor}
- * to execute tasks. This class arranges that submitted tasks are,
- * upon completion, placed on a queue accessible using <tt>take</tt>.
- * The class is lightweight enough to be suitable for transient use
- * when processing groups of tasks.
- *
- * <p>
- *
- * <b>Usage Examples.</b>
- *
- * Suppose you have a set of solvers for a certain problem, each
- * returning a value of some type <tt>Result</tt>, and would like to
- * run them concurrently, processing the results of each of them that
- * return a non-null value, in some method <tt>use(Result r)</tt>. You
- * could write this as:
- *
- * <pre>
- * void solve(Executor e,
- * Collection&lt;Callable&lt;Result&gt;&gt; solvers)
- * throws InterruptedException, ExecutionException {
- * CompletionService&lt;Result&gt; ecs
- * = new ExecutorCompletionService&lt;Result&gt;(e);
- * for (Callable&lt;Result&gt; s : solvers)
- * ecs.submit(s);
- * int n = solvers.size();
- * for (int i = 0; i &lt; n; ++i) {
- * Result r = ecs.take().get();
- * if (r != null)
- * use(r);
- * }
- * }
- * </pre>
- *
- * Suppose instead that you would like to use the first non-null result
- * of the set of tasks, ignoring any that encounter exceptions,
- * and cancelling all other tasks when the first one is ready:
- *
- * <pre>
- * void solve(Executor e,
- * Collection&lt;Callable&lt;Result&gt;&gt; solvers)
- * throws InterruptedException {
- * CompletionService&lt;Result&gt; ecs
- * = new ExecutorCompletionService&lt;Result&gt;(e);
- * int n = solvers.size();
- * List&lt;Future&lt;Result&gt;&gt; futures
- * = new ArrayList&lt;Future&lt;Result&gt;&gt;(n);
- * Result result = null;
- * try {
- * for (Callable&lt;Result&gt; s : solvers)
- * futures.add(ecs.submit(s));
- * for (int i = 0; i &lt; n; ++i) {
- * try {
- * Result r = ecs.take().get();
- * if (r != null) {
- * result = r;
- * break;
- * }
- * } catch (ExecutionException ignore) {}
- * }
- * }
- * finally {
- * for (Future&lt;Result&gt; f : futures)
- * f.cancel(true);
- * }
- *
- * if (result != null)
- * use(result);
- * }
- * </pre>
- */
-public class ExecutorCompletionService implements CompletionService {
- private final Executor executor;
- private final AbstractExecutorService aes;
- private final BlockingQueue completionQueue;
-
- /**
- * FutureTask extension to enqueue upon completion
- */
- private class QueueingFuture extends FutureTask {
- QueueingFuture(RunnableFuture task) {
- super(task, null);
- this.task = task;
- }
- protected void done() { completionQueue.add(task); }
- private final Future task;
- }
-
- private RunnableFuture newTaskFor(Callable task) {
- if (aes == null)
- return new FutureTask(task);
- else
- return aes.newTaskFor(task);
- }
-
- private RunnableFuture newTaskFor(Runnable task, Object result) {
- if (aes == null)
- return new FutureTask(task, result);
- else
- return aes.newTaskFor(task, result);
- }
-
- /**
- * Creates an ExecutorCompletionService using the supplied
- * executor for base task execution and a
- * {@link LinkedBlockingQueue} as a completion queue.
- *
- * @param executor the executor to use
- * @throws NullPointerException if executor is <tt>null</tt>
- */
- public ExecutorCompletionService(Executor executor) {
- if (executor == null)
- throw new NullPointerException();
- this.executor = executor;
- this.aes = (executor instanceof AbstractExecutorService) ?
- (AbstractExecutorService) executor : null;
- this.completionQueue = new LinkedBlockingQueue();
- }
-
- /**
- * Creates an ExecutorCompletionService using the supplied
- * executor for base task execution and the supplied queue as its
- * completion queue.
- *
- * @param executor the executor to use
- * @param completionQueue the queue to use as the completion queue
- * normally one dedicated for use by this service. This queue is
- * treated as unbounded -- failed attempted <tt>Queue.add</tt>
- * operations for completed tasks cause them not to be
- * retrievable.
- * @throws NullPointerException if executor or completionQueue are <tt>null</tt>
- */
- public ExecutorCompletionService(Executor executor,
- BlockingQueue completionQueue) {
- if (executor == null || completionQueue == null)
- throw new NullPointerException();
- this.executor = executor;
- this.aes = (executor instanceof AbstractExecutorService) ?
- (AbstractExecutorService) executor : null;
- this.completionQueue = completionQueue;
- }
-
- public Future submit(Callable task) {
- if (task == null) throw new NullPointerException();
- RunnableFuture f = newTaskFor(task);
- executor.execute(new QueueingFuture(f));
- return f;
- }
-
- public Future submit(Runnable task, Object result) {
- if (task == null) throw new NullPointerException();
- RunnableFuture f = newTaskFor(task, result);
- executor.execute(new QueueingFuture(f));
- return f;
- }
-
- public Future take() throws InterruptedException {
- return (Future)completionQueue.take();
- }
-
- public Future poll() {
- return (Future)completionQueue.poll();
- }
-
- public Future poll(long timeout, TimeUnit unit) throws InterruptedException {
- return (Future)completionQueue.poll(timeout, unit);
- }
-
-}
diff --git a/src/actors/scala/actors/threadpool/ExecutorService.java b/src/actors/scala/actors/threadpool/ExecutorService.java
deleted file mode 100644
index d3a9a3b8a8..0000000000
--- a/src/actors/scala/actors/threadpool/ExecutorService.java
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
- */
-
-package scala.actors.threadpool;
-
-import scala.actors.threadpool.*; // for javadoc (till 6280605 is fixed)
-import java.util.List;
-import java.util.Collection;
-
-/**
- * An {@link Executor} that provides methods to manage termination and
- * methods that can produce a {@link Future} for tracking progress of
- * one or more asynchronous tasks.
- *
- * <p> An <tt>ExecutorService</tt> can be shut down, which will cause
- * it to reject new tasks. Two different methods are provided for
- * shutting down an <tt>ExecutorService</tt>. The {@link #shutdown}
- * method will allow previously submitted tasks to execute before
- * terminating, while the {@link #shutdownNow} method prevents waiting
- * tasks from starting and attempts to stop currently executing tasks.
- * Upon termination, an executor has no tasks actively executing, no
- * tasks awaiting execution, and no new tasks can be submitted. An
- * unused <tt>ExecutorService</tt> should be shut down to allow
- * reclamation of its resources.
- *
- * <p> Method <tt>submit</tt> extends base method {@link
- * Executor#execute} by creating and returning a {@link Future} that
- * can be used to cancel execution and/or wait for completion.
- * Methods <tt>invokeAny</tt> and <tt>invokeAll</tt> perform the most
- * commonly useful forms of bulk execution, executing a collection of
- * tasks and then waiting for at least one, or all, to
- * complete. (Class {@link ExecutorCompletionService} can be used to
- * write customized variants of these methods.)
- *
- * <p>The {@link Executors} class provides factory methods for the
- * executor services provided in this package.
- *
- * <h3>Usage Example</h3>
- *
- * Here is a sketch of a network service in which threads in a thread
- * pool service incoming requests. It uses the preconfigured {@link
- * Executors#newFixedThreadPool} factory method:
- *
- * <pre>
- * class NetworkService implements Runnable {
- * private final ServerSocket serverSocket;
- * private final ExecutorService pool;
- *
- * public NetworkService(int port, int poolSize)
- * throws IOException {
- * serverSocket = new ServerSocket(port);
- * pool = Executors.newFixedThreadPool(poolSize);
- * }
- *
- * public void run() { // run the service
- * try {
- * for (;;) {
- * pool.execute(new Handler(serverSocket.accept()));
- * }
- * } catch (IOException ex) {
- * pool.shutdown();
- * }
- * }
- * }
- *
- * class Handler implements Runnable {
- * private final Socket socket;
- * Handler(Socket socket) { this.socket = socket; }
- * public void run() {
- * // read and service request on socket
- * }
- * }
- * </pre>
- *
- * The following method shuts down an <tt>ExecutorService</tt> in two phases,
- * first by calling <tt>shutdown</tt> to reject incoming tasks, and then
- * calling <tt>shutdownNow</tt>, if necessary, to cancel any lingering tasks:
- *
- * <pre>
- * void shutdownAndAwaitTermination(ExecutorService pool) {
- * pool.shutdown(); // Disable new tasks from being submitted
- * try {
- * // Wait a while for existing tasks to terminate
- * if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
- * pool.shutdownNow(); // Cancel currently executing tasks
- * // Wait a while for tasks to respond to being cancelled
- * if (!pool.awaitTermination(60, TimeUnit.SECONDS))
- * System.err.println("Pool did not terminate");
- * }
- * } catch (InterruptedException ie) {
- * // (Re-)Cancel if current thread also interrupted
- * pool.shutdownNow();
- * // Preserve interrupt status
- * Thread.currentThread().interrupt();
- * }
- * }
- * </pre>
- *
- * <p>Memory consistency effects: Actions in a thread prior to the
- * submission of a {@code Runnable} or {@code Callable} task to an
- * {@code ExecutorService}
- * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
- * any actions taken by that task, which in turn <i>happen-before</i> the
- * result is retrieved via {@code Future.get()}.
- *
- * @since 1.5
- * @author Doug Lea
- */
-public interface ExecutorService extends Executor {
-
- /**
- * Initiates an orderly shutdown in which previously submitted
- * tasks are executed, but no new tasks will be accepted.
- * Invocation has no additional effect if already shut down.
- *
- * @throws SecurityException if a security manager exists and
- * shutting down this ExecutorService may manipulate
- * threads that the caller is not permitted to modify
- * because it does not hold {@link
- * java.lang.RuntimePermission}<tt>("modifyThread")</tt>,
- * or the security manager's <tt>checkAccess</tt> method
- * denies access.
- */
- void shutdown();
-
- /**
- * Attempts to stop all actively executing tasks, halts the
- * processing of waiting tasks, and returns a list of the tasks that were
- * awaiting execution.
- *
- * <p>There are no guarantees beyond best-effort attempts to stop
- * processing actively executing tasks. For example, typical
- * implementations will cancel via {@link Thread#interrupt}, so any
- * task that fails to respond to interrupts may never terminate.
- *
- * @return list of tasks that never commenced execution
- * @throws SecurityException if a security manager exists and
- * shutting down this ExecutorService may manipulate
- * threads that the caller is not permitted to modify
- * because it does not hold {@link
- * java.lang.RuntimePermission}<tt>("modifyThread")</tt>,
- * or the security manager's <tt>checkAccess</tt> method
- * denies access.
- */
- List shutdownNow();
-
- /**
- * Returns <tt>true</tt> if this executor has been shut down.
- *
- * @return <tt>true</tt> if this executor has been shut down
- */
- boolean isShutdown();
-
- /**
- * Returns <tt>true</tt> if all tasks have completed following shut down.
- * Note that <tt>isTerminated</tt> is never <tt>true</tt> unless
- * either <tt>shutdown</tt> or <tt>shutdownNow</tt> was called first.
- *
- * @return <tt>true</tt> if all tasks have completed following shut down
- */
- boolean isTerminated();
-
- /**
- * Blocks until all tasks have completed execution after a shutdown
- * request, or the timeout occurs, or the current thread is
- * interrupted, whichever happens first.
- *
- * @param timeout the maximum time to wait
- * @param unit the time unit of the timeout argument
- * @return <tt>true</tt> if this executor terminated and
- * <tt>false</tt> if the timeout elapsed before termination
- * @throws InterruptedException if interrupted while waiting
- */
- boolean awaitTermination(long timeout, TimeUnit unit)
- throws InterruptedException;
-
-
- /**
- * Submits a value-returning task for execution and returns a
- * Future representing the pending results of the task. The
- * Future's <tt>get</tt> method will return the task's result upon
- * successful completion.
- *
- * <p>
- * If you would like to immediately block waiting
- * for a task, you can use constructions of the form
- * <tt>result = exec.submit(aCallable).get();</tt>
- *
- * <p> Note: The {@link Executors} class includes a set of methods
- * that can convert some other common closure-like objects,
- * for example, {@link java.security.PrivilegedAction} to
- * {@link Callable} form so they can be submitted.
- *
- * @param task the task to submit
- * @return a Future representing pending completion of the task
- * @throws RejectedExecutionException if the task cannot be
- * scheduled for execution
- * @throws NullPointerException if the task is null
- */
- Future submit(Callable task);
-
- /**
- * Submits a Runnable task for execution and returns a Future
- * representing that task. The Future's <tt>get</tt> method will
- * return the given result upon successful completion.
- *
- * @param task the task to submit
- * @param result the result to return
- * @return a Future representing pending completion of the task
- * @throws RejectedExecutionException if the task cannot be
- * scheduled for execution
- * @throws NullPointerException if the task is null
- */
- Future submit(Runnable task, Object result);
-
- /**
- * Submits a Runnable task for execution and returns a Future
- * representing that task. The Future's <tt>get</tt> method will
- * return <tt>null</tt> upon <em>successful</em> completion.
- *
- * @param task the task to submit
- * @return a Future representing pending completion of the task
- * @throws RejectedExecutionException if the task cannot be
- * scheduled for execution
- * @throws NullPointerException if the task is null
- */
- Future submit(Runnable task);
-
- /**
- * Executes the given tasks, returning a list of Futures holding
- * their status and results when all complete.
- * {@link Future#isDone} is <tt>true</tt> for each
- * element of the returned list.
- * Note that a <em>completed</em> task could have
- * terminated either normally or by throwing an exception.
- * The results of this method are undefined if the given
- * collection is modified while this operation is in progress.
- *
- * @param tasks the collection of tasks
- * @return A list of Futures representing the tasks, in the same
- * sequential order as produced by the iterator for the
- * given task list, each of which has completed.
- * @throws InterruptedException if interrupted while waiting, in
- * which case unfinished tasks are cancelled.
- * @throws NullPointerException if tasks or any of its elements are <tt>null</tt>
- * @throws RejectedExecutionException if any task cannot be
- * scheduled for execution
- */
-
- List invokeAll(Collection tasks)
- throws InterruptedException;
-
- /**
- * Executes the given tasks, returning a list of Futures holding
- * their status and results
- * when all complete or the timeout expires, whichever happens first.
- * {@link Future#isDone} is <tt>true</tt> for each
- * element of the returned list.
- * Upon return, tasks that have not completed are cancelled.
- * Note that a <em>completed</em> task could have
- * terminated either normally or by throwing an exception.
- * The results of this method are undefined if the given
- * collection is modified while this operation is in progress.
- *
- * @param tasks the collection of tasks
- * @param timeout the maximum time to wait
- * @param unit the time unit of the timeout argument
- * @return a list of Futures representing the tasks, in the same
- * sequential order as produced by the iterator for the
- * given task list. If the operation did not time out,
- * each task will have completed. If it did time out, some
- * of these tasks will not have completed.
- * @throws InterruptedException if interrupted while waiting, in
- * which case unfinished tasks are cancelled
- * @throws NullPointerException if tasks, any of its elements, or
- * unit are <tt>null</tt>
- * @throws RejectedExecutionException if any task cannot be scheduled
- * for execution
- */
- List invokeAll(Collection tasks, long timeout, TimeUnit unit)
- throws InterruptedException;
-
- /**
- * Executes the given tasks, returning the result
- * of one that has completed successfully (i.e., without throwing
- * an exception), if any do. Upon normal or exceptional return,
- * tasks that have not completed are cancelled.
- * The results of this method are undefined if the given
- * collection is modified while this operation is in progress.
- *
- * @param tasks the collection of tasks
- * @return the result returned by one of the tasks
- * @throws InterruptedException if interrupted while waiting
- * @throws NullPointerException if tasks or any of its elements
- * are <tt>null</tt>
- * @throws IllegalArgumentException if tasks is empty
- * @throws ExecutionException if no task successfully completes
- * @throws RejectedExecutionException if tasks cannot be scheduled
- * for execution
- */
- Object invokeAny(Collection tasks)
- throws InterruptedException, ExecutionException;
-
- /**
- * Executes the given tasks, returning the result
- * of one that has completed successfully (i.e., without throwing
- * an exception), if any do before the given timeout elapses.
- * Upon normal or exceptional return, tasks that have not
- * completed are cancelled.
- * The results of this method are undefined if the given
- * collection is modified while this operation is in progress.
- *
- * @param tasks the collection of tasks
- * @param timeout the maximum time to wait
- * @param unit the time unit of the timeout argument
- * @return the result returned by one of the tasks.
- * @throws InterruptedException if interrupted while waiting
- * @throws NullPointerException if tasks, any of its elements, or
- * unit are <tt>null</tt>
- * @throws TimeoutException if the given timeout elapses before
- * any task successfully completes
- * @throws ExecutionException if no task successfully completes
- * @throws RejectedExecutionException if tasks cannot be scheduled
- * for execution
- */
- Object invokeAny(Collection tasks, long timeout, TimeUnit unit)
- throws InterruptedException, ExecutionException, TimeoutException;
-}
diff --git a/src/actors/scala/actors/threadpool/Executors.java b/src/actors/scala/actors/threadpool/Executors.java
deleted file mode 100644
index 49a127a8db..0000000000
--- a/src/actors/scala/actors/threadpool/Executors.java
+++ /dev/null
@@ -1,667 +0,0 @@
-/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
- */
-
-package scala.actors.threadpool;
-//import edu.emory.mathcs.backport.java.util.*;
-import java.security.AccessControlContext;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.security.PrivilegedExceptionAction;
-import java.security.AccessControlException;
-import java.util.List;
-import java.util.Collection;
-
-/**
- * Factory and utility methods for {@link Executor}, {@link
- * ExecutorService}, {@link ScheduledExecutorService}, {@link
- * ThreadFactory}, and {@link Callable} classes defined in this
- * package. This class supports the following kinds of methods:
- *
- * <ul>
- * <li> Methods that create and return an {@link ExecutorService}
- * set up with commonly useful configuration settings.
- * <li> Methods that create and return a {@link ScheduledExecutorService}
- * set up with commonly useful configuration settings.
- * <li> Methods that create and return a "wrapped" ExecutorService, that
- * disables reconfiguration by making implementation-specific methods
- * inaccessible.
- * <li> Methods that create and return a {@link ThreadFactory}
- * that sets newly created threads to a known state.
- * <li> Methods that create and return a {@link Callable}
- * out of other closure-like forms, so they can be used
- * in execution methods requiring <tt>Callable</tt>.
- * </ul>
- *
- * @since 1.5
- * @author Doug Lea
- */
-public class Executors {
-
- /**
- * Creates a thread pool that reuses a fixed number of threads
- * operating off a shared unbounded queue. At any point, at most
- * <tt>nThreads</tt> threads will be active processing tasks.
- * If additional tasks are submitted when all threads are active,
- * they will wait in the queue until a thread is available.
- * If any thread terminates due to a failure during execution
- * prior to shutdown, a new one will take its place if needed to
- * execute subsequent tasks. The threads in the pool will exist
- * until it is explicitly {@link ExecutorService#shutdown shutdown}.
- *
- * @param nThreads the number of threads in the pool
- * @return the newly created thread pool
- * @throws IllegalArgumentException if <tt>nThreads &lt;= 0</tt>
- */
- public static ExecutorService newFixedThreadPool(int nThreads) {
- return new ThreadPoolExecutor(nThreads, nThreads,
- 0L, TimeUnit.MILLISECONDS,
- new LinkedBlockingQueue());
- }
-
- /**
- * Creates a thread pool that reuses a fixed number of threads
- * operating off a shared unbounded queue, using the provided
- * ThreadFactory to create new threads when needed. At any point,
- * at most <tt>nThreads</tt> threads will be active processing
- * tasks. If additional tasks are submitted when all threads are
- * active, they will wait in the queue until a thread is
- * available. If any thread terminates due to a failure during
- * execution prior to shutdown, a new one will take its place if
- * needed to execute subsequent tasks. The threads in the pool will
- * exist until it is explicitly {@link ExecutorService#shutdown
- * shutdown}.
- *
- * @param nThreads the number of threads in the pool
- * @param threadFactory the factory to use when creating new threads
- * @return the newly created thread pool
- * @throws NullPointerException if threadFactory is null
- * @throws IllegalArgumentException if <tt>nThreads &lt;= 0</tt>
- */
- public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
- return new ThreadPoolExecutor(nThreads, nThreads,
- 0L, TimeUnit.MILLISECONDS,
- new LinkedBlockingQueue(),
- threadFactory);
- }
-
- /**
- * Creates an Executor that uses a single worker thread operating
- * off an unbounded queue. (Note however that if this single
- * thread terminates due to a failure during execution prior to
- * shutdown, a new one will take its place if needed to execute
- * subsequent tasks.) Tasks are guaranteed to execute
- * sequentially, and no more than one task will be active at any
- * given time. Unlike the otherwise equivalent
- * <tt>newFixedThreadPool(1)</tt> the returned executor is
- * guaranteed not to be reconfigurable to use additional threads.
- *
- * @return the newly created single-threaded Executor
- */
- public static ExecutorService newSingleThreadExecutor() {
- return new FinalizableDelegatedExecutorService
- (new ThreadPoolExecutor(1, 1,
- 0L, TimeUnit.MILLISECONDS,
- new LinkedBlockingQueue()));
- }
-
- /**
- * Creates an Executor that uses a single worker thread operating
- * off an unbounded queue, and uses the provided ThreadFactory to
- * create a new thread when needed. Unlike the otherwise
- * equivalent <tt>newFixedThreadPool(1, threadFactory)</tt> the
- * returned executor is guaranteed not to be reconfigurable to use
- * additional threads.
- *
- * @param threadFactory the factory to use when creating new
- * threads
- *
- * @return the newly created single-threaded Executor
- * @throws NullPointerException if threadFactory is null
- */
- public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
- return new FinalizableDelegatedExecutorService
- (new ThreadPoolExecutor(1, 1,
- 0L, TimeUnit.MILLISECONDS,
- new LinkedBlockingQueue(),
- threadFactory));
- }
-
- /**
- * Creates a thread pool that creates new threads as needed, but
- * will reuse previously constructed threads when they are
- * available. These pools will typically improve the performance
- * of programs that execute many short-lived asynchronous tasks.
- * Calls to <tt>execute</tt> will reuse previously constructed
- * threads if available. If no existing thread is available, a new
- * thread will be created and added to the pool. Threads that have
- * not been used for sixty seconds are terminated and removed from
- * the cache. Thus, a pool that remains idle for long enough will
- * not consume any resources. Note that pools with similar
- * properties but different details (for example, timeout parameters)
- * may be created using {@link ThreadPoolExecutor} constructors.
- *
- * @return the newly created thread pool
- */
- public static ExecutorService newCachedThreadPool() {
- return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
- 60L, TimeUnit.SECONDS,
- new SynchronousQueue());
- }
-
- /**
- * Creates a thread pool that creates new threads as needed, but
- * will reuse previously constructed threads when they are
- * available, and uses the provided
- * ThreadFactory to create new threads when needed.
- * @param threadFactory the factory to use when creating new threads
- * @return the newly created thread pool
- * @throws NullPointerException if threadFactory is null
- */
- public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
- return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
- 60L, TimeUnit.SECONDS,
- new SynchronousQueue(),
- threadFactory);
- }
-
- /**
- * Creates a single-threaded executor that can schedule commands
- * to run after a given delay, or to execute periodically.
- * (Note however that if this single
- * thread terminates due to a failure during execution prior to
- * shutdown, a new one will take its place if needed to execute
- * subsequent tasks.) Tasks are guaranteed to execute
- * sequentially, and no more than one task will be active at any
- * given time. Unlike the otherwise equivalent
- * <tt>newScheduledThreadPool(1)</tt> the returned executor is
- * guaranteed not to be reconfigurable to use additional threads.
- * @return the newly created scheduled executor
- */
- /* public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
- return new DelegatedScheduledExecutorService
- (new ScheduledThreadPoolExecutor(1));
- }
- */
- /**
- * Creates a single-threaded executor that can schedule commands
- * to run after a given delay, or to execute periodically. (Note
- * however that if this single thread terminates due to a failure
- * during execution prior to shutdown, a new one will take its
- * place if needed to execute subsequent tasks.) Tasks are
- * guaranteed to execute sequentially, and no more than one task
- * will be active at any given time. Unlike the otherwise
- * equivalent <tt>newScheduledThreadPool(1, threadFactory)</tt>
- * the returned executor is guaranteed not to be reconfigurable to
- * use additional threads.
- * @param threadFactory the factory to use when creating new
- * threads
- * @return a newly created scheduled executor
- * @throws NullPointerException if threadFactory is null
- */
- /* public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) {
- return new DelegatedScheduledExecutorService
- (new ScheduledThreadPoolExecutor(1, threadFactory));
- }
- */
- /**
- * Creates a thread pool that can schedule commands to run after a
- * given delay, or to execute periodically.
- * @param corePoolSize the number of threads to keep in the pool,
- * even if they are idle.
- * @return a newly created scheduled thread pool
- * @throws IllegalArgumentException if <tt>corePoolSize &lt; 0</tt>
- */
- /* public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
- return new ScheduledThreadPoolExecutor(corePoolSize);
- }
- */
- /**
- * Creates a thread pool that can schedule commands to run after a
- * given delay, or to execute periodically.
- * @param corePoolSize the number of threads to keep in the pool,
- * even if they are idle.
- * @param threadFactory the factory to use when the executor
- * creates a new thread.
- * @return a newly created scheduled thread pool
- * @throws IllegalArgumentException if <tt>corePoolSize &lt; 0</tt>
- * @throws NullPointerException if threadFactory is null
- */
- /* public static ScheduledExecutorService newScheduledThreadPool(
- int corePoolSize, ThreadFactory threadFactory) {
- return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
- }
- */
-
- /**
- * Returns an object that delegates all defined {@link
- * ExecutorService} methods to the given executor, but not any
- * other methods that might otherwise be accessible using
- * casts. This provides a way to safely "freeze" configuration and
- * disallow tuning of a given concrete implementation.
- * @param executor the underlying implementation
- * @return an <tt>ExecutorService</tt> instance
- * @throws NullPointerException if executor null
- */
- public static ExecutorService unconfigurableExecutorService(ExecutorService executor) {
- if (executor == null)
- throw new NullPointerException();
- return new DelegatedExecutorService(executor);
- }
-
- /**
- * Returns an object that delegates all defined {@link
- * ScheduledExecutorService} methods to the given executor, but
- * not any other methods that might otherwise be accessible using
- * casts. This provides a way to safely "freeze" configuration and
- * disallow tuning of a given concrete implementation.
- * @param executor the underlying implementation
- * @return a <tt>ScheduledExecutorService</tt> instance
- * @throws NullPointerException if executor null
- */
- /* public static ScheduledExecutorService unconfigurableScheduledExecutorService(ScheduledExecutorService executor) {
- if (executor == null)
- throw new NullPointerException();
- return new DelegatedScheduledExecutorService(executor);
- }
- */
- /**
- * Returns a default thread factory used to create new threads.
- * This factory creates all new threads used by an Executor in the
- * same {@link ThreadGroup}. If there is a {@link
- * java.lang.SecurityManager}, it uses the group of {@link
- * System#getSecurityManager}, else the group of the thread
- * invoking this <tt>defaultThreadFactory</tt> method. Each new
- * thread is created as a non-daemon thread with priority set to
- * the smaller of <tt>Thread.NORM_PRIORITY</tt> and the maximum
- * priority permitted in the thread group. New threads have names
- * accessible via {@link Thread#getName} of
- * <em>pool-N-thread-M</em>, where <em>N</em> is the sequence
- * number of this factory, and <em>M</em> is the sequence number
- * of the thread created by this factory.
- * @return a thread factory
- */
- public static ThreadFactory defaultThreadFactory() {
- return new DefaultThreadFactory();
- }
-
- /**
- * Returns a thread factory used to create new threads that
- * have the same permissions as the current thread.
- * This factory creates threads with the same settings as {@link
- * Executors#defaultThreadFactory}, additionally setting the
- * AccessControlContext and contextClassLoader of new threads to
- * be the same as the thread invoking this
- * <tt>privilegedThreadFactory</tt> method. A new
- * <tt>privilegedThreadFactory</tt> can be created within an
- * {@link AccessController#doPrivileged} action setting the
- * current thread's access control context to create threads with
- * the selected permission settings holding within that action.
- *
- * <p> Note that while tasks running within such threads will have
- * the same access control and class loader settings as the
- * current thread, they need not have the same {@link
- * java.lang.ThreadLocal} or {@link
- * java.lang.InheritableThreadLocal} values. If necessary,
- * particular values of thread locals can be set or reset before
- * any task runs in {@link ThreadPoolExecutor} subclasses using
- * {@link ThreadPoolExecutor#beforeExecute}. Also, if it is
- * necessary to initialize worker threads to have the same
- * InheritableThreadLocal settings as some other designated
- * thread, you can create a custom ThreadFactory in which that
- * thread waits for and services requests to create others that
- * will inherit its values.
- *
- * @return a thread factory
- * @throws AccessControlException if the current access control
- * context does not have permission to both get and set context
- * class loader.
- */
- public static ThreadFactory privilegedThreadFactory() {
- return new PrivilegedThreadFactory();
- }
-
- /**
- * Returns a {@link Callable} object that, when
- * called, runs the given task and returns the given result. This
- * can be useful when applying methods requiring a
- * <tt>Callable</tt> to an otherwise resultless action.
- * @param task the task to run
- * @param result the result to return
- * @return a callable object
- * @throws NullPointerException if task null
- */
- public static Callable callable(Runnable task, Object result) {
- if (task == null)
- throw new NullPointerException();
- return new RunnableAdapter(task, result);
- }
-
- /**
- * Returns a {@link Callable} object that, when
- * called, runs the given task and returns <tt>null</tt>.
- * @param task the task to run
- * @return a callable object
- * @throws NullPointerException if task null
- */
- public static Callable callable(Runnable task) {
- if (task == null)
- throw new NullPointerException();
- return new RunnableAdapter(task, null);
- }
-
- /**
- * Returns a {@link Callable} object that, when
- * called, runs the given privileged action and returns its result.
- * @param action the privileged action to run
- * @return a callable object
- * @throws NullPointerException if action null
- */
- public static Callable callable(final PrivilegedAction action) {
- if (action == null)
- throw new NullPointerException();
- return new Callable() {
- public Object call() { return action.run(); }};
- }
-
- /**
- * Returns a {@link Callable} object that, when
- * called, runs the given privileged exception action and returns
- * its result.
- * @param action the privileged exception action to run
- * @return a callable object
- * @throws NullPointerException if action null
- */
- public static Callable callable(final PrivilegedExceptionAction action) {
- if (action == null)
- throw new NullPointerException();
- return new Callable() {
- public Object call() throws Exception { return action.run(); }};
- }
-
- /**
- * Returns a {@link Callable} object that will, when
- * called, execute the given <tt>callable</tt> under the current
- * access control context. This method should normally be
- * invoked within an {@link AccessController#doPrivileged} action
- * to create callables that will, if possible, execute under the
- * selected permission settings holding within that action; or if
- * not possible, throw an associated {@link
- * AccessControlException}.
- * @param callable the underlying task
- * @return a callable object
- * @throws NullPointerException if callable null
- *
- */
- public static Callable privilegedCallable(Callable callable) {
- if (callable == null)
- throw new NullPointerException();
- return new PrivilegedCallable(callable);
- }
-
- /**
- * Returns a {@link Callable} object that will, when
- * called, execute the given <tt>callable</tt> under the current
- * access control context, with the current context class loader
- * as the context class loader. This method should normally be
- * invoked within an {@link AccessController#doPrivileged} action
- * to create callables that will, if possible, execute under the
- * selected permission settings holding within that action; or if
- * not possible, throw an associated {@link
- * AccessControlException}.
- * @param callable the underlying task
- *
- * @return a callable object
- * @throws NullPointerException if callable null
- * @throws AccessControlException if the current access control
- * context does not have permission to both set and get context
- * class loader.
- */
- public static Callable privilegedCallableUsingCurrentClassLoader(Callable callable) {
- if (callable == null)
- throw new NullPointerException();
- return new PrivilegedCallableUsingCurrentClassLoader(callable);
- }
-
- // Non-public classes supporting the public methods
-
- /**
- * A callable that runs given task and returns given result
- */
- static final class RunnableAdapter implements Callable {
- final Runnable task;
- final Object result;
- RunnableAdapter(Runnable task, Object result) {
- this.task = task;
- this.result = result;
- }
- public Object call() {
- task.run();
- return result;
- }
- }
-
- /**
- * A callable that runs under established access control settings
- */
- static final class PrivilegedCallable implements Callable {
- private final AccessControlContext acc;
- private final Callable task;
- private Object result;
- private Exception exception;
- PrivilegedCallable(Callable task) {
- this.task = task;
- this.acc = AccessController.getContext();
- }
-
- public Object call() throws Exception {
- AccessController.doPrivileged(new PrivilegedAction() {
- public Object run() {
- try {
- result = task.call();
- } catch (Exception ex) {
- exception = ex;
- }
- return null;
- }
- }, acc);
- if (exception != null)
- throw exception;
- else
- return result;
- }
- }
-
- /**
- * A callable that runs under established access control settings and
- * current ClassLoader
- */
- static final class PrivilegedCallableUsingCurrentClassLoader implements Callable {
- private final ClassLoader ccl;
- private final AccessControlContext acc;
- private final Callable task;
- private Object result;
- private Exception exception;
- PrivilegedCallableUsingCurrentClassLoader(Callable task) {
- this.task = task;
- this.ccl = Thread.currentThread().getContextClassLoader();
- this.acc = AccessController.getContext();
- acc.checkPermission(new RuntimePermission("getContextClassLoader"));
- acc.checkPermission(new RuntimePermission("setContextClassLoader"));
- }
-
- public Object call() throws Exception {
- AccessController.doPrivileged(new PrivilegedAction() {
- public Object run() {
- ClassLoader savedcl = null;
- Thread t = Thread.currentThread();
- try {
- ClassLoader cl = t.getContextClassLoader();
- if (ccl != cl) {
- t.setContextClassLoader(ccl);
- savedcl = cl;
- }
- result = task.call();
- } catch (Exception ex) {
- exception = ex;
- } finally {
- if (savedcl != null)
- t.setContextClassLoader(savedcl);
- }
- return null;
- }
- }, acc);
- if (exception != null)
- throw exception;
- else
- return result;
- }
- }
-
- /**
- * The default thread factory
- */
- static class DefaultThreadFactory implements ThreadFactory {
- static final AtomicInteger poolNumber = new AtomicInteger(1);
- final ThreadGroup group;
- final AtomicInteger threadNumber = new AtomicInteger(1);
- final String namePrefix;
-
- DefaultThreadFactory() {
- SecurityManager s = System.getSecurityManager();
- group = (s != null)? s.getThreadGroup() :
- Thread.currentThread().getThreadGroup();
- namePrefix = "pool-" +
- poolNumber.getAndIncrement() +
- "-thread-";
- }
-
- public Thread newThread(Runnable r) {
- Thread t = new Thread(group, r,
- namePrefix + threadNumber.getAndIncrement(),
- 0);
- if (t.isDaemon())
- t.setDaemon(false);
- if (t.getPriority() != Thread.NORM_PRIORITY)
- t.setPriority(Thread.NORM_PRIORITY);
- return t;
- }
- }
-
- /**
- * Thread factory capturing access control and class loader
- */
- static class PrivilegedThreadFactory extends DefaultThreadFactory {
- private final ClassLoader ccl;
- private final AccessControlContext acc;
-
- PrivilegedThreadFactory() {
- super();
- this.ccl = Thread.currentThread().getContextClassLoader();
- this.acc = AccessController.getContext();
- acc.checkPermission(new RuntimePermission("setContextClassLoader"));
- }
-
- public Thread newThread(final Runnable r) {
- return super.newThread(new Runnable() {
- public void run() {
- AccessController.doPrivileged(new PrivilegedAction() {
- public Object run() {
- Thread.currentThread().setContextClassLoader(ccl);
- r.run();
- return null;
- }
- }, acc);
- }
- });
- }
-
- }
-
- /**
- * A wrapper class that exposes only the ExecutorService methods
- * of an ExecutorService implementation.
- */
- static class DelegatedExecutorService extends AbstractExecutorService {
- private final ExecutorService e;
- DelegatedExecutorService(ExecutorService executor) { e = executor; }
- public void execute(Runnable command) { e.execute(command); }
- public void shutdown() { e.shutdown(); }
- public List shutdownNow() { return e.shutdownNow(); }
- public boolean isShutdown() { return e.isShutdown(); }
- public boolean isTerminated() { return e.isTerminated(); }
- public boolean awaitTermination(long timeout, TimeUnit unit)
- throws InterruptedException {
- return e.awaitTermination(timeout, unit);
- }
- public Future submit(Runnable task) {
- return e.submit(task);
- }
- public Future submit(Callable task) {
- return e.submit(task);
- }
- public Future submit(Runnable task, Object result) {
- return e.submit(task, result);
- }
- public List<Future> invokeAll(Collection tasks)
- throws InterruptedException {
- return e.invokeAll(tasks);
- }
- public List<Future> invokeAll(Collection tasks,
- long timeout, TimeUnit unit)
- throws InterruptedException {
- return e.invokeAll(tasks, timeout, unit);
- }
- public Object invokeAny(Collection tasks)
- throws InterruptedException, ExecutionException {
- return e.invokeAny(tasks);
- }
- public Object invokeAny(Collection tasks,
- long timeout, TimeUnit unit)
- throws InterruptedException, ExecutionException, TimeoutException {
- return e.invokeAny(tasks, timeout, unit);
- }
- }
-
- static class FinalizableDelegatedExecutorService
- extends DelegatedExecutorService {
- FinalizableDelegatedExecutorService(ExecutorService executor) {
- super(executor);
- }
- protected void finalize() {
- super.shutdown();
- }
- }
-
- /**
- * A wrapper class that exposes only the ScheduledExecutorService
- * methods of a ScheduledExecutorService implementation.
- */
- /* static class DelegatedScheduledExecutorService
- extends DelegatedExecutorService
- implements ScheduledExecutorService {
- private final ScheduledExecutorService e;
- DelegatedScheduledExecutorService(ScheduledExecutorService executor) {
- super(executor);
- e = executor;
- }
- public ScheduledFuture schedule(Runnable command, long delay, TimeUnit unit) {
- return e.schedule(command, delay, unit);
- }
- public ScheduledFuture schedule(Callable callable, long delay, TimeUnit unit) {
- return e.schedule(callable, delay, unit);
- }
- public ScheduledFuture scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) {
- return e.scheduleAtFixedRate(command, initialDelay, period, unit);
- }
- public ScheduledFuture scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) {
- return e.scheduleWithFixedDelay(command, initialDelay, delay, unit);
- }
- }
-*/
-
- /** Cannot instantiate. */
- private Executors() {}
-}
diff --git a/src/actors/scala/actors/threadpool/Future.java b/src/actors/scala/actors/threadpool/Future.java
deleted file mode 100644
index 5e1b3d414a..0000000000
--- a/src/actors/scala/actors/threadpool/Future.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
- */
-
-package scala.actors.threadpool;
-import scala.actors.threadpool.*; // for javadoc (till 6280605 is fixed)
-
-/**
- * A <tt>Future</tt> represents the result of an asynchronous
- * computation. Methods are provided to check if the computation is
- * complete, to wait for its completion, and to retrieve the result of
- * the computation. The result can only be retrieved using method
- * <tt>get</tt> when the computation has completed, blocking if
- * necessary until it is ready. Cancellation is performed by the
- * <tt>cancel</tt> method. Additional methods are provided to
- * determine if the task completed normally or was cancelled. Once a
- * computation has completed, the computation cannot be cancelled.
- * If you would like to use a <tt>Future</tt> for the sake
- * of cancellability but not provide a usable result, you can
- * declare types of the form <tt>Future&lt;?&gt;</tt> and
- * return <tt>null</tt> as a result of the underlying task.
- *
- * <p>
- * <b>Sample Usage</b> (Note that the following classes are all
- * made-up.) <p>
- * <pre>
- * interface ArchiveSearcher { String search(String target); }
- * class App {
- * ExecutorService executor = ...
- * ArchiveSearcher searcher = ...
- * void showSearch(final String target)
- * throws InterruptedException {
- * Future&lt;String&gt; future
- * = executor.submit(new Callable&lt;String&gt;() {
- * public String call() {
- * return searcher.search(target);
- * }});
- * displayOtherThings(); // do other things while searching
- * try {
- * displayText(future.get()); // use future
- * } catch (ExecutionException ex) { cleanup(); return; }
- * }
- * }
- * </pre>
- *
- * The {@link FutureTask} class is an implementation of <tt>Future</tt> that
- * implements <tt>Runnable</tt>, and so may be executed by an <tt>Executor</tt>.
- * For example, the above construction with <tt>submit</tt> could be replaced by:
- * <pre>
- * FutureTask&lt;String&gt; future =
- * new FutureTask&lt;String&gt;(new Callable&lt;String&gt;() {
- * public String call() {
- * return searcher.search(target);
- * }});
- * executor.execute(future);
- * </pre>
- *
- * <p>Memory consistency effects: Actions taken by the asynchronous computation
- * <a href="package-summary.html#MemoryVisibility"> <i>happen-before</i></a>
- * actions following the corresponding {@code Future.get()} in another thread.
- *
- * @see FutureTask
- * @see Executor
- * @since 1.5
- * @author Doug Lea
- */
-public interface Future {
-
- /**
- * Attempts to cancel execution of this task. This attempt will
- * fail if the task has already completed, has already been cancelled,
- * or could not be cancelled for some other reason. If successful,
- * and this task has not started when <tt>cancel</tt> is called,
- * this task should never run. If the task has already started,
- * then the <tt>mayInterruptIfRunning</tt> parameter determines
- * whether the thread executing this task should be interrupted in
- * an attempt to stop the task.
- *
- * <p>After this method returns, subsequent calls to {@link #isDone} will
- * always return <tt>true</tt>. Subsequent calls to {@link #isCancelled}
- * will always return <tt>true</tt> if this method returned <tt>true</tt>.
- *
- * @param mayInterruptIfRunning <tt>true</tt> if the thread executing this
- * task should be interrupted; otherwise, in-progress tasks are allowed
- * to complete
- * @return <tt>false</tt> if the task could not be cancelled,
- * typically because it has already completed normally;
- * <tt>true</tt> otherwise
- */
- boolean cancel(boolean mayInterruptIfRunning);
-
- /**
- * Returns <tt>true</tt> if this task was cancelled before it completed
- * normally.
- *
- * @return <tt>true</tt> if this task was cancelled before it completed
- */
- boolean isCancelled();
-
- /**
- * Returns <tt>true</tt> if this task completed.
- *
- * Completion may be due to normal termination, an exception, or
- * cancellation -- in all of these cases, this method will return
- * <tt>true</tt>.
- *
- * @return <tt>true</tt> if this task completed
- */
- boolean isDone();
-
- /**
- * Waits if necessary for the computation to complete, and then
- * retrieves its result.
- *
- * @return the computed result
- * @throws CancellationException if the computation was cancelled
- * @throws ExecutionException if the computation threw an
- * exception
- * @throws InterruptedException if the current thread was interrupted
- * while waiting
- */
- Object get() throws InterruptedException, ExecutionException;
-
- /**
- * Waits if necessary for at most the given time for the computation
- * to complete, and then retrieves its result, if available.
- *
- * @param timeout the maximum time to wait
- * @param unit the time unit of the timeout argument
- * @return the computed result
- * @throws CancellationException if the computation was cancelled
- * @throws ExecutionException if the computation threw an
- * exception
- * @throws InterruptedException if the current thread was interrupted
- * while waiting
- * @throws TimeoutException if the wait timed out
- */
- Object get(long timeout, TimeUnit unit)
- throws InterruptedException, ExecutionException, TimeoutException;
-}
diff --git a/src/actors/scala/actors/threadpool/FutureTask.java b/src/actors/scala/actors/threadpool/FutureTask.java
deleted file mode 100644
index d4dcfe38b3..0000000000
--- a/src/actors/scala/actors/threadpool/FutureTask.java
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain. Use, modify, and
- * redistribute this code in any way without acknowledgement.
- */
-
-package scala.actors.threadpool;
-
-import scala.actors.threadpool.*; // for javadoc
-import scala.actors.threadpool.helpers.*;
-
-/**
- * A cancellable asynchronous computation. This class provides a base
- * implementation of {@link Future}, with methods to start and cancel
- * a computation, query to see if the computation is complete, and
- * retrieve the result of the computation. The result can only be
- * retrieved when the computation has completed; the <tt>get</tt>
- * method will block if the computation has not yet completed. Once
- * the computation has completed, the computation cannot be restarted
- * or cancelled.
- *
- * <p>A <tt>FutureTask</tt> can be used to wrap a {@link Callable} or
- * {@link java.lang.Runnable} object. Because <tt>FutureTask</tt>
- * implements <tt>Runnable</tt>, a <tt>FutureTask</tt> can be
- * submitted to an {@link Executor} for execution.
- *
- * <p>In addition to serving as a standalone class, this class provides
- * <tt>protected</tt> functionality that may be useful when creating
- * customized task classes.
- *
- * @since 1.5
- * @author Doug Lea
- */
-public class FutureTask implements RunnableFuture {
-
- /** State value representing that task is ready to run */
- private static final int READY = 0;
- /** State value representing that task is running */
- private static final int RUNNING = 1;
- /** State value representing that task ran */
- private static final int RAN = 2;
- /** State value representing that task was cancelled */
- private static final int CANCELLED = 4;
-
- /** The underlying callable */
- private final Callable callable;
- /** The result to return from get() */
- private Object result;
- /** The exception to throw from get() */
- private Throwable exception;
-
- private int state;
-
- /**
- * The thread running task. When nulled after set/cancel, this
- * indicates that the results are accessible. Must be
- * volatile, to ensure visibility upon completion.
- */
- private volatile Thread runner;
-
- /**
- * Creates a <tt>FutureTask</tt> that will, upon running, execute the
- * given <tt>Callable</tt>.
- *
- * @param callable the callable task
- * @throws NullPointerException if callable is null
- */
- public FutureTask(Callable callable) {
- if (callable == null)
- throw new NullPointerException();
- this.callable = callable;
- }
-
- /**
- * Creates a <tt>FutureTask</tt> that will, upon running, execute the
- * given <tt>Runnable</tt>, and arrange that <tt>get</tt> will return the
- * given result on successful completion.
- *
- * @param runnable the runnable task
- * @param result the result to return on successful completion. If
- * you don't need a particular result, consider using
- * constructions of the form:
- * <tt>Future&lt;?&gt; f = new FutureTask&lt;Object&gt;(runnable, null)</tt>
- * @throws NullPointerException if runnable is null
- */
- public FutureTask(Runnable runnable, Object result) {
- this(Executors.callable(runnable, result));
- }
-
- public synchronized boolean isCancelled() {
- return state == CANCELLED;
- }
-
- public synchronized boolean isDone() {
- return ranOrCancelled() && runner == null;
- }
-
- public boolean cancel(boolean mayInterruptIfRunning) {
- synchronized (this) {
- if (ranOrCancelled()) return false;
- state = CANCELLED;
- if (mayInterruptIfRunning) {
- Thread r = runner;
- if (r != null) r.interrupt();
- }
- runner = null;
- notifyAll();
- }
- done();
- return true;
- }
-
- /**
- * @throws CancellationException {@inheritDoc}
- */
- public synchronized Object get()
- throws InterruptedException, ExecutionException
- {
- waitFor();
- return getResult();
- }
-
- /**
- * @throws CancellationException {@inheritDoc}
- */
- public synchronized Object get(long timeout, TimeUnit unit)
- throws InterruptedException, ExecutionException, TimeoutException
- {
- waitFor(unit.toNanos(timeout));
- return getResult();
- }
-
- /**
- * Protected method invoked when this task transitions to state
- * <tt>isDone</tt> (whether normally or via cancellation). The
- * default implementation does nothing. Subclasses may override
- * this method to invoke completion callbacks or perform
- * bookkeeping. Note that you can query status inside the
- * implementation of this method to determine whether this task
- * has been cancelled.
- */
- protected void done() { }
-
- /**
- * Sets the result of this Future to the given value unless
- * this future has already been set or has been cancelled.
- * This method is invoked internally by the <tt>run</tt> method
- * upon successful completion of the computation.
- * @param v the value
- */
- protected void set(Object v) {
- setCompleted(v);
- }
-
- /**
- * Causes this future to report an <tt>ExecutionException</tt>
- * with the given throwable as its cause, unless this Future has
- * already been set or has been cancelled.
- * This method is invoked internally by the <tt>run</tt> method
- * upon failure of the computation.
- * @param t the cause of failure
- */
- protected void setException(Throwable t) {
- setFailed(t);
- }
-
- /**
- * Sets this Future to the result of its computation
- * unless it has been cancelled.
- */
- public void run() {
- synchronized (this) {
- if (state != READY) return;
- state = RUNNING;
- runner = Thread.currentThread();
- }
- try {
- set(callable.call());
- }
- catch (Throwable ex) {
- setException(ex);
- }
- }
-
- /**
- * Executes the computation without setting its result, and then
- * resets this Future to initial state, failing to do so if the
- * computation encounters an exception or is cancelled. This is
- * designed for use with tasks that intrinsically execute more
- * than once.
- * @return true if successfully run and reset
- */
- protected boolean runAndReset() {
- synchronized (this) {
- if (state != READY) return false;
- state = RUNNING;
- runner = Thread.currentThread();
- }
- try {
- callable.call(); // don't set result
- synchronized (this) {
- runner = null;
- if (state == RUNNING) {
- state = READY;
- return true;
- }
- else {
- return false;
- }
- }
- }
- catch (Throwable ex) {
- setException(ex);
- return false;
- }
- }
-
- // PRE: lock owned
- private boolean ranOrCancelled() {
- return (state & (RAN | CANCELLED)) != 0;
- }
-
- /**
- * Marks the task as completed.
- * @param result the result of a task.
- */
- private void setCompleted(Object result) {
- synchronized (this) {
- if (ranOrCancelled()) return;
- this.state = RAN;
- this.result = result;
- this.runner = null;
- notifyAll();
- }
-
- // invoking callbacks *after* setting future as completed and
- // outside the synchronization block makes it safe to call
- // interrupt() from within callback code (in which case it will be
- // ignored rather than cause deadlock / illegal state exception)
- done();
- }
-
- /**
- * Marks the task as failed.
- * @param exception the cause of abrupt completion.
- */
- private void setFailed(Throwable exception) {
- synchronized (this) {
- if (ranOrCancelled()) return;
- this.state = RAN;
- this.exception = exception;
- this.runner = null;
- notifyAll();
- }
-
- // invoking callbacks *after* setting future as completed and
- // outside the synchronization block makes it safe to call
- // interrupt() from within callback code (in which case it will be
- // ignored rather than cause deadlock / illegal state exception)
- done();
- }
-
- /**
- * Waits for the task to complete.
- * PRE: lock owned
- */
- private void waitFor() throws InterruptedException {
- while (!isDone()) {
- wait();
- }
- }
-
- /**
- * Waits for the task to complete for timeout nanoseconds or throw
- * TimeoutException if still not completed after that
- * PRE: lock owned
- */
- private void waitFor(long nanos) throws InterruptedException, TimeoutException {
- if (nanos < 0) throw new IllegalArgumentException();
- if (isDone()) return;
- long deadline = Utils.nanoTime() + nanos;
- while (nanos > 0) {
- TimeUnit.NANOSECONDS.timedWait(this, nanos);
- if (isDone()) return;
- nanos = deadline - Utils.nanoTime();
- }
- throw new TimeoutException();
- }
-
- /**
- * Gets the result of the task.
- *
- * PRE: task completed
- * PRE: lock owned
- */
- private Object getResult() throws ExecutionException {
- if (state == CANCELLED) {
- throw new CancellationException();
- }
- if (exception != null) {
- throw new ExecutionException(exception);
- }
- return result;
- }
-
- // todo: consider
- //public String toString() {
- // return callable.toString();
- //}
-}
diff --git a/src/actors/scala/actors/threadpool/LinkedBlockingQueue.java b/src/actors/scala/actors/threadpool/LinkedBlockingQueue.java
deleted file mode 100644
index 15f1085ec6..0000000000
--- a/src/actors/scala/actors/threadpool/LinkedBlockingQueue.java
+++ /dev/null
@@ -1,843 +0,0 @@
-/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
- */
-
-package scala.actors.threadpool;
-
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.locks.Condition;
-import java.util.concurrent.locks.ReentrantLock;
-import java.util.AbstractQueue;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-/**
- * An optionally-bounded {@linkplain BlockingQueue blocking queue} based on
- * linked nodes.
- * This queue orders elements FIFO (first-in-first-out).
- * The <em>head</em> of the queue is that element that has been on the
- * queue the longest time.
- * The <em>tail</em> of the queue is that element that has been on the
- * queue the shortest time. New elements
- * are inserted at the tail of the queue, and the queue retrieval
- * operations obtain elements at the head of the queue.
- * Linked queues typically have higher throughput than array-based queues but
- * less predictable performance in most concurrent applications.
- *
- * <p> The optional capacity bound constructor argument serves as a
- * way to prevent excessive queue expansion. The capacity, if unspecified,
- * is equal to {@link Integer#MAX_VALUE}. Linked nodes are
- * dynamically created upon each insertion unless this would bring the
- * queue above capacity.
- *
- * <p>This class and its iterator implement all of the
- * <em>optional</em> methods of the {@link Collection} and {@link
- * Iterator} interfaces.
- *
- * <p>This class is a member of the
- * <a href="{@docRoot}/../technotes/guides/collections/index.html">
- * Java Collections Framework</a>.
- *
- * @since 1.5
- * @author Doug Lea
- * @param <E> the type of elements held in this collection
- *
- */
-public class LinkedBlockingQueue<E> extends java.util.AbstractQueue<E>
- implements BlockingQueue<E>, java.io.Serializable {
- private static final long serialVersionUID = -6903933977591709194L;
-
- /*
- * A variant of the "two lock queue" algorithm. The putLock gates
- * entry to put (and offer), and has an associated condition for
- * waiting puts. Similarly for the takeLock. The "count" field
- * that they both rely on is maintained as an atomic to avoid
- * needing to get both locks in most cases. Also, to minimize need
- * for puts to get takeLock and vice-versa, cascading notifies are
- * used. When a put notices that it has enabled at least one take,
- * it signals taker. That taker in turn signals others if more
- * items have been entered since the signal. And symmetrically for
- * takes signalling puts. Operations such as remove(Object) and
- * iterators acquire both locks.
- *
- * Visibility between writers and readers is provided as follows:
- *
- * Whenever an element is enqueued, the putLock is acquired and
- * count updated. A subsequent reader guarantees visibility to the
- * enqueued Node by either acquiring the putLock (via fullyLock)
- * or by acquiring the takeLock, and then reading n = count.get();
- * this gives visibility to the first n items.
- *
- * To implement weakly consistent iterators, it appears we need to
- * keep all Nodes GC-reachable from a predecessor dequeued Node.
- * That would cause two problems:
- * - allow a rogue Iterator to cause unbounded memory retention
- * - cause cross-generational linking of old Nodes to new Nodes if
- * a Node was tenured while live, which generational GCs have a
- * hard time dealing with, causing repeated major collections.
- * However, only non-deleted Nodes need to be reachable from
- * dequeued Nodes, and reachability does not necessarily have to
- * be of the kind understood by the GC. We use the trick of
- * linking a Node that has just been dequeued to itself. Such a
- * self-link implicitly means to advance to head.next.
- */
-
- /**
- * Linked list node class
- */
- static class Node<E> {
- E item;
-
- /**
- * One of:
- * - the real successor Node
- * - this Node, meaning the successor is head.next
- * - null, meaning there is no successor (this is the last node)
- */
- Node<E> next;
-
- Node(E x) { item = x; }
- }
-
- /** The capacity bound, or Integer.MAX_VALUE if none */
- private final int capacity;
-
- /** Current number of elements */
- private final AtomicInteger count = new AtomicInteger(0);
-
- /**
- * Head of linked list.
- * Invariant: head.item == null
- */
- private transient Node<E> head;
-
- /**
- * Tail of linked list.
- * Invariant: last.next == null
- */
- private transient Node<E> last;
-
- /** Lock held by take, poll, etc */
- private final ReentrantLock takeLock = new ReentrantLock();
-
- /** Wait queue for waiting takes */
- private final Condition notEmpty = takeLock.newCondition();
-
- /** Lock held by put, offer, etc */
- private final ReentrantLock putLock = new ReentrantLock();
-
- /** Wait queue for waiting puts */
- private final Condition notFull = putLock.newCondition();
-
- /**
- * Signals a waiting take. Called only from put/offer (which do not
- * otherwise ordinarily lock takeLock.)
- */
- private void signalNotEmpty() {
- final ReentrantLock takeLock = this.takeLock;
- takeLock.lock();
- try {
- notEmpty.signal();
- } finally {
- takeLock.unlock();
- }
- }
-
- /**
- * Signals a waiting put. Called only from take/poll.
- */
- private void signalNotFull() {
- final ReentrantLock putLock = this.putLock;
- putLock.lock();
- try {
- notFull.signal();
- } finally {
- putLock.unlock();
- }
- }
-
- /**
- * Creates a node and links it at end of queue.
- *
- * @param x the item
- */
- private void enqueue(E x) {
- // assert putLock.isHeldByCurrentThread();
- // assert last.next == null;
- last = last.next = new Node<E>(x);
- }
-
- /**
- * Removes a node from head of queue.
- *
- * @return the node
- */
- private E dequeue() {
- // assert takeLock.isHeldByCurrentThread();
- // assert head.item == null;
- Node<E> h = head;
- Node<E> first = h.next;
- h.next = h; // help GC
- head = first;
- E x = first.item;
- first.item = null;
- return x;
- }
-
- /**
- * Lock to prevent both puts and takes.
- */
- void fullyLock() {
- putLock.lock();
- takeLock.lock();
- }
-
- /**
- * Unlock to allow both puts and takes.
- */
- void fullyUnlock() {
- takeLock.unlock();
- putLock.unlock();
- }
-
-// /**
-// * Tells whether both locks are held by current thread.
-// */
-// boolean isFullyLocked() {
-// return (putLock.isHeldByCurrentThread() &&
-// takeLock.isHeldByCurrentThread());
-// }
-
- /**
- * Creates a {@code LinkedBlockingQueue} with a capacity of
- * {@link Integer#MAX_VALUE}.
- */
- public LinkedBlockingQueue() {
- this(Integer.MAX_VALUE);
- }
-
- /**
- * Creates a {@code LinkedBlockingQueue} with the given (fixed) capacity.
- *
- * @param capacity the capacity of this queue
- * @throws IllegalArgumentException if {@code capacity} is not greater
- * than zero
- */
- public LinkedBlockingQueue(int capacity) {
- if (capacity <= 0) throw new IllegalArgumentException();
- this.capacity = capacity;
- last = head = new Node<E>(null);
- }
-
- /**
- * Creates a {@code LinkedBlockingQueue} with a capacity of
- * {@link Integer#MAX_VALUE}, initially containing the elements of the
- * given collection,
- * added in traversal order of the collection's iterator.
- *
- * @param c the collection of elements to initially contain
- * @throws NullPointerException if the specified collection or any
- * of its elements are null
- */
- public LinkedBlockingQueue(Collection<? extends E> c) {
- this(Integer.MAX_VALUE);
- final ReentrantLock putLock = this.putLock;
- putLock.lock(); // Never contended, but necessary for visibility
- try {
- int n = 0;
- for (E e : c) {
- if (e == null)
- throw new NullPointerException();
- if (n == capacity)
- throw new IllegalStateException("Queue full");
- enqueue(e);
- ++n;
- }
- count.set(n);
- } finally {
- putLock.unlock();
- }
- }
-
-
- // this doc comment is overridden to remove the reference to collections
- // greater in size than Integer.MAX_VALUE
- /**
- * Returns the number of elements in this queue.
- *
- * @return the number of elements in this queue
- */
- public int size() {
- return count.get();
- }
-
- // this doc comment is a modified copy of the inherited doc comment,
- // without the reference to unlimited queues.
- /**
- * Returns the number of additional elements that this queue can ideally
- * (in the absence of memory or resource constraints) accept without
- * blocking. This is always equal to the initial capacity of this queue
- * less the current {@code size} of this queue.
- *
- * <p>Note that you <em>cannot</em> always tell if an attempt to insert
- * an element will succeed by inspecting {@code remainingCapacity}
- * because it may be the case that another thread is about to
- * insert or remove an element.
- */
- public int remainingCapacity() {
- return capacity - count.get();
- }
-
- /**
- * Inserts the specified element at the tail of this queue, waiting if
- * necessary for space to become available.
- *
- * @throws InterruptedException {@inheritDoc}
- * @throws NullPointerException {@inheritDoc}
- */
- public void put(E e) throws InterruptedException {
- if (e == null) throw new NullPointerException();
- // Note: convention in all put/take/etc is to preset local var
- // holding count negative to indicate failure unless set.
- int c = -1;
- final ReentrantLock putLock = this.putLock;
- final AtomicInteger count = this.count;
- putLock.lockInterruptibly();
- try {
- /*
- * Note that count is used in wait guard even though it is
- * not protected by lock. This works because count can
- * only decrease at this point (all other puts are shut
- * out by lock), and we (or some other waiting put) are
- * signalled if it ever changes from capacity. Similarly
- * for all other uses of count in other wait guards.
- */
- while (count.get() == capacity) {
- notFull.await();
- }
- enqueue(e);
- c = count.getAndIncrement();
- if (c + 1 < capacity)
- notFull.signal();
- } finally {
- putLock.unlock();
- }
- if (c == 0)
- signalNotEmpty();
- }
-
- /**
- * Inserts the specified element at the tail of this queue, waiting if
- * necessary up to the specified wait time for space to become available.
- *
- * @return {@code true} if successful, or {@code false} if
- * the specified waiting time elapses before space is available.
- * @throws InterruptedException {@inheritDoc}
- * @throws NullPointerException {@inheritDoc}
- */
- public boolean offer(E e, long timeout, TimeUnit unit)
- throws InterruptedException {
-
- if (e == null) throw new NullPointerException();
- long nanos = unit.toNanos(timeout);
- int c = -1;
- final ReentrantLock putLock = this.putLock;
- final AtomicInteger count = this.count;
- putLock.lockInterruptibly();
- try {
- while (count.get() == capacity) {
- if (nanos <= 0)
- return false;
- nanos = notFull.awaitNanos(nanos);
- }
- enqueue(e);
- c = count.getAndIncrement();
- if (c + 1 < capacity)
- notFull.signal();
- } finally {
- putLock.unlock();
- }
- if (c == 0)
- signalNotEmpty();
- return true;
- }
-
- /**
- * Inserts the specified element at the tail of this queue if it is
- * possible to do so immediately without exceeding the queue's capacity,
- * returning {@code true} upon success and {@code false} if this queue
- * is full.
- * When using a capacity-restricted queue, this method is generally
- * preferable to method {@link BlockingQueue#add add}, which can fail to
- * insert an element only by throwing an exception.
- *
- * @throws NullPointerException if the specified element is null
- */
- public boolean offer(E e) {
- if (e == null) throw new NullPointerException();
- final AtomicInteger count = this.count;
- if (count.get() == capacity)
- return false;
- int c = -1;
- final ReentrantLock putLock = this.putLock;
- putLock.lock();
- try {
- if (count.get() < capacity) {
- enqueue(e);
- c = count.getAndIncrement();
- if (c + 1 < capacity)
- notFull.signal();
- }
- } finally {
- putLock.unlock();
- }
- if (c == 0)
- signalNotEmpty();
- return c >= 0;
- }
-
-
- public E take() throws InterruptedException {
- E x;
- int c = -1;
- final AtomicInteger count = this.count;
- final ReentrantLock takeLock = this.takeLock;
- takeLock.lockInterruptibly();
- try {
- while (count.get() == 0) {
- notEmpty.await();
- }
- x = dequeue();
- c = count.getAndDecrement();
- if (c > 1)
- notEmpty.signal();
- } finally {
- takeLock.unlock();
- }
- if (c == capacity)
- signalNotFull();
- return x;
- }
-
- public E poll(long timeout, TimeUnit unit) throws InterruptedException {
- E x = null;
- int c = -1;
- long nanos = unit.toNanos(timeout);
- final AtomicInteger count = this.count;
- final ReentrantLock takeLock = this.takeLock;
- takeLock.lockInterruptibly();
- try {
- while (count.get() == 0) {
- if (nanos <= 0)
- return null;
- nanos = notEmpty.awaitNanos(nanos);
- }
- x = dequeue();
- c = count.getAndDecrement();
- if (c > 1)
- notEmpty.signal();
- } finally {
- takeLock.unlock();
- }
- if (c == capacity)
- signalNotFull();
- return x;
- }
-
- public E poll() {
- final AtomicInteger count = this.count;
- if (count.get() == 0)
- return null;
- E x = null;
- int c = -1;
- final ReentrantLock takeLock = this.takeLock;
- takeLock.lock();
- try {
- if (count.get() > 0) {
- x = dequeue();
- c = count.getAndDecrement();
- if (c > 1)
- notEmpty.signal();
- }
- } finally {
- takeLock.unlock();
- }
- if (c == capacity)
- signalNotFull();
- return x;
- }
-
- public E peek() {
- if (count.get() == 0)
- return null;
- final ReentrantLock takeLock = this.takeLock;
- takeLock.lock();
- try {
- Node<E> first = head.next;
- if (first == null)
- return null;
- else
- return first.item;
- } finally {
- takeLock.unlock();
- }
- }
-
- /**
- * Unlinks interior Node p with predecessor trail.
- */
- void unlink(Node<E> p, Node<E> trail) {
- // assert isFullyLocked();
- // p.next is not changed, to allow iterators that are
- // traversing p to maintain their weak-consistency guarantee.
- p.item = null;
- trail.next = p.next;
- if (last == p)
- last = trail;
- if (count.getAndDecrement() == capacity)
- notFull.signal();
- }
-
- /**
- * Removes a single instance of the specified element from this queue,
- * if it is present. More formally, removes an element {@code e} such
- * that {@code o.equals(e)}, if this queue contains one or more such
- * elements.
- * Returns {@code true} if this queue contained the specified element
- * (or equivalently, if this queue changed as a result of the call).
- *
- * @param o element to be removed from this queue, if present
- * @return {@code true} if this queue changed as a result of the call
- */
- public boolean remove(Object o) {
- if (o == null) return false;
- fullyLock();
- try {
- for (Node<E> trail = head, p = trail.next;
- p != null;
- trail = p, p = p.next) {
- if (o.equals(p.item)) {
- unlink(p, trail);
- return true;
- }
- }
- return false;
- } finally {
- fullyUnlock();
- }
- }
-
- /**
- * Returns an array containing all of the elements in this queue, in
- * proper sequence.
- *
- * <p>The returned array will be "safe" in that no references to it are
- * maintained by this queue. (In other words, this method must allocate
- * a new array). The caller is thus free to modify the returned array.
- *
- * <p>This method acts as bridge between array-based and collection-based
- * APIs.
- *
- * @return an array containing all of the elements in this queue
- */
- public Object[] toArray() {
- fullyLock();
- try {
- int size = count.get();
- Object[] a = new Object[size];
- int k = 0;
- for (Node<E> p = head.next; p != null; p = p.next)
- a[k++] = p.item;
- return a;
- } finally {
- fullyUnlock();
- }
- }
-
- /**
- * Returns an array containing all of the elements in this queue, in
- * proper sequence; the runtime type of the returned array is that of
- * the specified array. If the queue fits in the specified array, it
- * is returned therein. Otherwise, a new array is allocated with the
- * runtime type of the specified array and the size of this queue.
- *
- * <p>If this queue fits in the specified array with room to spare
- * (i.e., the array has more elements than this queue), the element in
- * the array immediately following the end of the queue is set to
- * {@code null}.
- *
- * <p>Like the {@link #toArray()} method, this method acts as bridge between
- * array-based and collection-based APIs. Further, this method allows
- * precise control over the runtime type of the output array, and may,
- * under certain circumstances, be used to save allocation costs.
- *
- * <p>Suppose {@code x} is a queue known to contain only strings.
- * The following code can be used to dump the queue into a newly
- * allocated array of {@code String}:
- *
- * <pre>
- * String[] y = x.toArray(new String[0]);</pre>
- *
- * Note that {@code toArray(new Object[0])} is identical in function to
- * {@code toArray()}.
- *
- * @param a the array into which the elements of the queue are to
- * be stored, if it is big enough; otherwise, a new array of the
- * same runtime type is allocated for this purpose
- * @return an array containing all of the elements in this queue
- * @throws ArrayStoreException if the runtime type of the specified array
- * is not a supertype of the runtime type of every element in
- * this queue
- * @throws NullPointerException if the specified array is null
- */
- @SuppressWarnings("unchecked")
- public <T> T[] toArray(T[] a) {
- fullyLock();
- try {
- int size = count.get();
- if (a.length < size)
- a = (T[])java.lang.reflect.Array.newInstance
- (a.getClass().getComponentType(), size);
-
- int k = 0;
- for (Node<E> p = head.next; p != null; p = p.next)
- a[k++] = (T)p.item;
- if (a.length > k)
- a[k] = null;
- return a;
- } finally {
- fullyUnlock();
- }
- }
-
- public String toString() {
- fullyLock();
- try {
- return super.toString();
- } finally {
- fullyUnlock();
- }
- }
-
- /**
- * Atomically removes all of the elements from this queue.
- * The queue will be empty after this call returns.
- */
- public void clear() {
- fullyLock();
- try {
- for (Node<E> p, h = head; (p = h.next) != null; h = p) {
- h.next = h;
- p.item = null;
- }
- head = last;
- // assert head.item == null && head.next == null;
- if (count.getAndSet(0) == capacity)
- notFull.signal();
- } finally {
- fullyUnlock();
- }
- }
-
- /**
- * @throws UnsupportedOperationException {@inheritDoc}
- * @throws ClassCastException {@inheritDoc}
- * @throws NullPointerException {@inheritDoc}
- * @throws IllegalArgumentException {@inheritDoc}
- */
- public int drainTo(Collection<? super E> c) {
- return drainTo(c, Integer.MAX_VALUE);
- }
-
- /**
- * @throws UnsupportedOperationException {@inheritDoc}
- * @throws ClassCastException {@inheritDoc}
- * @throws NullPointerException {@inheritDoc}
- * @throws IllegalArgumentException {@inheritDoc}
- */
- public int drainTo(Collection<? super E> c, int maxElements) {
- if (c == null)
- throw new NullPointerException();
- if (c == this)
- throw new IllegalArgumentException();
- boolean signalNotFull = false;
- final ReentrantLock takeLock = this.takeLock;
- takeLock.lock();
- try {
- int n = Math.min(maxElements, count.get());
- // count.get provides visibility to first n Nodes
- Node<E> h = head;
- int i = 0;
- try {
- while (i < n) {
- Node<E> p = h.next;
- c.add(p.item);
- p.item = null;
- h.next = h;
- h = p;
- ++i;
- }
- return n;
- } finally {
- // Restore invariants even if c.add() threw
- if (i > 0) {
- // assert h.item == null;
- head = h;
- signalNotFull = (count.getAndAdd(-i) == capacity);
- }
- }
- } finally {
- takeLock.unlock();
- if (signalNotFull)
- signalNotFull();
- }
- }
-
- /**
- * Returns an iterator over the elements in this queue in proper sequence.
- * The returned {@code Iterator} is a "weakly consistent" iterator that
- * will never throw {@link java.util.ConcurrentModificationException
- * ConcurrentModificationException},
- * and guarantees to traverse elements as they existed upon
- * construction of the iterator, and may (but is not guaranteed to)
- * reflect any modifications subsequent to construction.
- *
- * @return an iterator over the elements in this queue in proper sequence
- */
- public Iterator<E> iterator() {
- return new Itr();
- }
-
- private class Itr implements Iterator<E> {
- /*
- * Basic weakly-consistent iterator. At all times hold the next
- * item to hand out so that if hasNext() reports true, we will
- * still have it to return even if lost race with a take etc.
- */
- private Node<E> current;
- private Node<E> lastRet;
- private E currentElement;
-
- Itr() {
- fullyLock();
- try {
- current = head.next;
- if (current != null)
- currentElement = current.item;
- } finally {
- fullyUnlock();
- }
- }
-
- public boolean hasNext() {
- return current != null;
- }
-
- /**
- * Returns the next live successor of p, or null if no such.
- *
- * Unlike other traversal methods, iterators need to handle both:
- * - dequeued nodes (p.next == p)
- * - (possibly multiple) interior removed nodes (p.item == null)
- */
- private Node<E> nextNode(Node<E> p) {
- for (;;) {
- Node<E> s = p.next;
- if (s == p)
- return head.next;
- if (s == null || s.item != null)
- return s;
- p = s;
- }
- }
-
- public E next() {
- fullyLock();
- try {
- if (current == null)
- throw new NoSuchElementException();
- E x = currentElement;
- lastRet = current;
- current = nextNode(current);
- currentElement = (current == null) ? null : current.item;
- return x;
- } finally {
- fullyUnlock();
- }
- }
-
- public void remove() {
- if (lastRet == null)
- throw new IllegalStateException();
- fullyLock();
- try {
- Node<E> node = lastRet;
- lastRet = null;
- for (Node<E> trail = head, p = trail.next;
- p != null;
- trail = p, p = p.next) {
- if (p == node) {
- unlink(p, trail);
- break;
- }
- }
- } finally {
- fullyUnlock();
- }
- }
- }
-
- /**
- * Save the state to a stream (that is, serialize it).
- *
- * @serialData The capacity is emitted (int), followed by all of
- * its elements (each an {@code Object}) in the proper order,
- * followed by a null
- * @param s the stream
- */
- private void writeObject(java.io.ObjectOutputStream s)
- throws java.io.IOException {
-
- fullyLock();
- try {
- // Write out any hidden stuff, plus capacity
- s.defaultWriteObject();
-
- // Write out all elements in the proper order.
- for (Node<E> p = head.next; p != null; p = p.next)
- s.writeObject(p.item);
-
- // Use trailing null as sentinel
- s.writeObject(null);
- } finally {
- fullyUnlock();
- }
- }
-
- /**
- * Reconstitute this queue instance from a stream (that is,
- * deserialize it).
- *
- * @param s the stream
- */
- private void readObject(java.io.ObjectInputStream s)
- throws java.io.IOException, ClassNotFoundException {
- // Read in capacity, and any hidden stuff
- s.defaultReadObject();
-
- count.set(0);
- last = head = new Node<E>(null);
-
- // Read in all elements and place in queue
- for (;;) {
- @SuppressWarnings("unchecked")
- E item = (E)s.readObject();
- if (item == null)
- break;
- add(item);
- }
- }
-}
diff --git a/src/actors/scala/actors/threadpool/Perf.java b/src/actors/scala/actors/threadpool/Perf.java
deleted file mode 100644
index 0f262b444f..0000000000
--- a/src/actors/scala/actors/threadpool/Perf.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package scala.actors.threadpool;
-
-/**
- * Compilation stub for pre-1.4.2 JREs. Thanks to it, the whole backport
- * package compiles and works with 1.4.2 as well as wih earlier JREs, and takes
- * advantage of native Perf class when running on 1.4.2 while seamlessly
- * falling back to System.currentTimeMillis() on previous JREs. This class
- * should NOT be included in the binary distribution of backport.
- *
- * @author Dawid Kurzyniec
- * @version 1.0
- */
-public final class Perf {
-
- private static final Perf perf = new Perf();
-
- public static Perf getPerf() { return perf; }
-
- private Perf() {}
-
- public long highResCounter() {
- return System.currentTimeMillis();
- }
-
- public long highResFrequency() {
- return 1000L;
- }
-}
diff --git a/src/actors/scala/actors/threadpool/Queue.java b/src/actors/scala/actors/threadpool/Queue.java
deleted file mode 100644
index f952e9d94c..0000000000
--- a/src/actors/scala/actors/threadpool/Queue.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
- */
-
-package scala.actors.threadpool;
-
-import java.util.Collection;
-
-/**
- * A collection designed for holding elements prior to processing.
- * Besides basic {@link java.util.Collection Collection} operations,
- * queues provide additional insertion, extraction, and inspection
- * operations. Each of these methods exists in two forms: one throws
- * an exception if the operation fails, the other returns a special
- * value (either <tt>null</tt> or <tt>false</tt>, depending on the
- * operation). The latter form of the insert operation is designed
- * specifically for use with capacity-restricted <tt>Queue</tt>
- * implementations; in most implementations, insert operations cannot
- * fail.
- *
- * <p>
- * <table BORDER CELLPADDING=3 CELLSPACING=1>
- * <tr>
- * <td></td>
- * <td ALIGN=CENTER><em>Throws exception</em></td>
- * <td ALIGN=CENTER><em>Returns special value</em></td>
- * </tr>
- * <tr>
- * <td><b>Insert</b></td>
- * <td>{@link #add add(e)}</td>
- * <td>{@link #offer offer(e)}</td>
- * </tr>
- * <tr>
- * <td><b>Remove</b></td>
- * <td>{@link #remove remove()}</td>
- * <td>{@link #poll poll()}</td>
- * </tr>
- * <tr>
- * <td><b>Examine</b></td>
- * <td>{@link #element element()}</td>
- * <td>{@link #peek peek()}</td>
- * </tr>
- * </table>
- *
- * <p>Queues typically, but do not necessarily, order elements in a
- * FIFO (first-in-first-out) manner. Among the exceptions are
- * priority queues, which order elements according to a supplied
- * comparator, or the elements' natural ordering, and LIFO queues (or
- * stacks) which order the elements LIFO (last-in-first-out).
- * Whatever the ordering used, the <em>head</em> of the queue is that
- * element which would be removed by a call to {@link #remove() } or
- * {@link #poll()}. In a FIFO queue, all new elements are inserted at
- * the <em> tail</em> of the queue. Other kinds of queues may use
- * different placement rules. Every <tt>Queue</tt> implementation
- * must specify its ordering properties.
- *
- * <p>The {@link #offer offer} method inserts an element if possible,
- * otherwise returning <tt>false</tt>. This differs from the {@link
- * java.util.Collection#add Collection.add} method, which can fail to
- * add an element only by throwing an unchecked exception. The
- * <tt>offer</tt> method is designed for use when failure is a normal,
- * rather than exceptional occurrence, for example, in fixed-capacity
- * (or &quot;bounded&quot;) queues.
- *
- * <p>The {@link #remove()} and {@link #poll()} methods remove and
- * return the head of the queue.
- * Exactly which element is removed from the queue is a
- * function of the queue's ordering policy, which differs from
- * implementation to implementation. The <tt>remove()</tt> and
- * <tt>poll()</tt> methods differ only in their behavior when the
- * queue is empty: the <tt>remove()</tt> method throws an exception,
- * while the <tt>poll()</tt> method returns <tt>null</tt>.
- *
- * <p>The {@link #element()} and {@link #peek()} methods return, but do
- * not remove, the head of the queue.
- *
- * <p>The <tt>Queue</tt> interface does not define the <i>blocking queue
- * methods</i>, which are common in concurrent programming. These methods,
- * which wait for elements to appear or for space to become available, are
- * defined in the {@link edu.emory.mathcs.backport.java.util.concurrent.BlockingQueue} interface, which
- * extends this interface.
- *
- * <p><tt>Queue</tt> implementations generally do not allow insertion
- * of <tt>null</tt> elements, although some implementations, such as
- * {@link LinkedList}, do not prohibit insertion of <tt>null</tt>.
- * Even in the implementations that permit it, <tt>null</tt> should
- * not be inserted into a <tt>Queue</tt>, as <tt>null</tt> is also
- * used as a special return value by the <tt>poll</tt> method to
- * indicate that the queue contains no elements.
- *
- * <p><tt>Queue</tt> implementations generally do not define
- * element-based versions of methods <tt>equals</tt> and
- * <tt>hashCode</tt> but instead inherit the identity based versions
- * from class <tt>Object</tt>, because element-based equality is not
- * always well-defined for queues with the same elements but different
- * ordering properties.
- *
- *
- * <p>This interface is a member of the
- * <a href="{@docRoot}/../technotes/guides/collections/index.html">
- * Java Collections Framework</a>.
- *
- * @see java.util.Collection
- * @see LinkedList
- * @see PriorityQueue
- * @see edu.emory.mathcs.backport.java.util.concurrent.LinkedBlockingQueue
- * @see edu.emory.mathcs.backport.java.util.concurrent.BlockingQueue
- * @see edu.emory.mathcs.backport.java.util.concurrent.ArrayBlockingQueue
- * @see edu.emory.mathcs.backport.java.util.concurrent.LinkedBlockingQueue
- * @see edu.emory.mathcs.backport.java.util.concurrent.PriorityBlockingQueue
- * @since 1.5
- * @author Doug Lea
- */
-public interface Queue extends Collection {
- /**
- * Inserts the specified element into this queue if it is possible to do so
- * immediately without violating capacity restrictions, returning
- * <tt>true</tt> upon success and throwing an <tt>IllegalStateException</tt>
- * if no space is currently available.
- *
- * @param e the element to add
- * @return <tt>true</tt> (as specified by {@link Collection#add})
- * @throws IllegalStateException if the element cannot be added at this
- * time due to capacity restrictions
- * @throws ClassCastException if the class of the specified element
- * prevents it from being added to this queue
- * @throws NullPointerException if the specified element is null and
- * this queue not permit null elements
- * @throws IllegalArgumentException if some property of this element
- * prevents it from being added to this queue
- */
- boolean add(Object e);
-
- /**
- * Inserts the specified element into this queue if it is possible to do
- * so immediately without violating capacity restrictions.
- * When using a capacity-restricted queue, this method is generally
- * preferable to {@link #add}, which can fail to insert an element only
- * by throwing an exception.
- *
- * @param e the element to add
- * @return <tt>true</tt> if the element was added to this queue, else
- * <tt>false</tt>
- * @throws ClassCastException if the class of the specified element
- * prevents it from being added to this queue
- * @throws NullPointerException if the specified element is null and
- * this queue does not permit null elements
- * @throws IllegalArgumentException if some property of this element
- * prevents it from being added to this queue
- */
- boolean offer(Object e);
-
- /**
- * Retrieves and removes the head of this queue. This method differs
- * from {@link #poll poll} only in that it throws an exception if this
- * queue is empty.
- * is empty.
- *
- * @return the head of this queue
- * @throws NoSuchElementException if this queue is empty
- */
- Object remove();
-
- /**
- * Retrieves and removes the head of this queue,
- * or returns <tt>null</tt> if this queue is empty.
- *
- * @return the head of this queue, or <tt>null</tt> if this queue is empty
- */
- Object poll();
-
- /**
- * Retrieves, but does not remove, the head of this queue. This method
- * differs from {@link #peek peek} only in that it throws an exception
- * if this queue is empty.
- *
- * @return the head of this queue
- * @throws NoSuchElementException if this queue is empty
- */
- Object element();
-
- /**
- * Retrieves, but does not remove, the head of this queue,
- * or returns <tt>null</tt> if this queue is empty.
- *
- * @return the head of this queue, or <tt>null</tt> if this queue is empty
- */
- Object peek();
-}
diff --git a/src/actors/scala/actors/threadpool/RejectedExecutionException.java b/src/actors/scala/actors/threadpool/RejectedExecutionException.java
deleted file mode 100644
index 1b61d35974..0000000000
--- a/src/actors/scala/actors/threadpool/RejectedExecutionException.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
- */
-
-package scala.actors.threadpool;
-
-/**
- * Exception thrown by an {@link Executor} when a task cannot be
- * accepted for execution.
- *
- * @since 1.5
- * @author Doug Lea
- */
-public class RejectedExecutionException extends RuntimeException {
- private static final long serialVersionUID = -375805702767069545L;
-
- /**
- * Constructs a <tt>RejectedExecutionException</tt> with no detail message.
- * The cause is not initialized, and may subsequently be
- * initialized by a call to {@link #initCause(Throwable) initCause}.
- */
- public RejectedExecutionException() { }
-
- /**
- * Constructs a <tt>RejectedExecutionException</tt> with the
- * specified detail message. The cause is not initialized, and may
- * subsequently be initialized by a call to {@link
- * #initCause(Throwable) initCause}.
- *
- * @param message the detail message
- */
- public RejectedExecutionException(String message) {
- super(message);
- }
-
- /**
- * Constructs a <tt>RejectedExecutionException</tt> with the
- * specified detail message and cause.
- *
- * @param message the detail message
- * @param cause the cause (which is saved for later retrieval by the
- * {@link #getCause()} method)
- */
- public RejectedExecutionException(String message, Throwable cause) {
- super(message, cause);
- }
-
- /**
- * Constructs a <tt>RejectedExecutionException</tt> with the
- * specified cause. The detail message is set to: <pre> (cause ==
- * null ? null : cause.toString())</pre> (which typically contains
- * the class and detail message of <tt>cause</tt>).
- *
- * @param cause the cause (which is saved for later retrieval by the
- * {@link #getCause()} method)
- */
- public RejectedExecutionException(Throwable cause) {
- super(cause);
- }
-}
diff --git a/src/actors/scala/actors/threadpool/RejectedExecutionHandler.java b/src/actors/scala/actors/threadpool/RejectedExecutionHandler.java
deleted file mode 100644
index 86e6d18a40..0000000000
--- a/src/actors/scala/actors/threadpool/RejectedExecutionHandler.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
- */
-
-package scala.actors.threadpool;
-
-/**
- * A handler for tasks that cannot be executed by a {@link ThreadPoolExecutor}.
- *
- * @since 1.5
- * @author Doug Lea
- */
-public interface RejectedExecutionHandler {
-
- /**
- * Method that may be invoked by a {@link ThreadPoolExecutor} when
- * {@link ThreadPoolExecutor#execute execute} cannot accept a
- * task. This may occur when no more threads or queue slots are
- * available because their bounds would be exceeded, or upon
- * shutdown of the Executor.
- *
- * <p>In the absence of other alternatives, the method may throw
- * an unchecked {@link RejectedExecutionException}, which will be
- * propagated to the caller of {@code execute}.
- *
- * @param r the runnable task requested to be executed
- * @param executor the executor attempting to execute this task
- * @throws RejectedExecutionException if there is no remedy
- */
-
- void rejectedExecution(Runnable r, ThreadPoolExecutor executor);
-}
diff --git a/src/actors/scala/actors/threadpool/RunnableFuture.java b/src/actors/scala/actors/threadpool/RunnableFuture.java
deleted file mode 100644
index bbd63a2d92..0000000000
--- a/src/actors/scala/actors/threadpool/RunnableFuture.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
- */
-
-package scala.actors.threadpool;
-
-/**
- * A {@link Future} that is {@link Runnable}. Successful execution of
- * the <tt>run</tt> method causes completion of the <tt>Future</tt>
- * and allows access to its results.
- * @see FutureTask
- * @see Executor
- * @since 1.6
- * @author Doug Lea
- */
-public interface RunnableFuture extends Runnable, Future {
- /**
- * Sets this Future to the result of its computation
- * unless it has been cancelled.
- */
- void run();
-}
diff --git a/src/actors/scala/actors/threadpool/SynchronousQueue.java b/src/actors/scala/actors/threadpool/SynchronousQueue.java
deleted file mode 100644
index 739b0043dd..0000000000
--- a/src/actors/scala/actors/threadpool/SynchronousQueue.java
+++ /dev/null
@@ -1,833 +0,0 @@
-/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
- */
-
-package scala.actors.threadpool;
-import scala.actors.threadpool.locks.*;
-//import edu.emory.mathcs.backport.java.util.*;
-import java.util.Collection;
-import java.util.Iterator;
-import scala.actors.threadpool.helpers.Utils;
-import java.util.NoSuchElementException;
-
-/**
- * A {@linkplain BlockingQueue blocking queue} in which each insert
- * operation must wait for a corresponding remove operation by another
- * thread, and vice versa. A synchronous queue does not have any
- * internal capacity, not even a capacity of one. You cannot
- * <tt>peek</tt> at a synchronous queue because an element is only
- * present when you try to remove it; you cannot insert an element
- * (using any method) unless another thread is trying to remove it;
- * you cannot iterate as there is nothing to iterate. The
- * <em>head</em> of the queue is the element that the first queued
- * inserting thread is trying to add to the queue; if there is no such
- * queued thread then no element is available for removal and
- * <tt>poll()</tt> will return <tt>null</tt>. For purposes of other
- * <tt>Collection</tt> methods (for example <tt>contains</tt>), a
- * <tt>SynchronousQueue</tt> acts as an empty collection. This queue
- * does not permit <tt>null</tt> elements.
- *
- * <p>Synchronous queues are similar to rendezvous channels used in
- * CSP and Ada. They are well suited for handoff designs, in which an
- * object running in one thread must sync up with an object running
- * in another thread in order to hand it some information, event, or
- * task.
- *
- * <p> This class supports an optional fairness policy for ordering
- * waiting producer and consumer threads. By default, this ordering
- * is not guaranteed. However, a queue constructed with fairness set
- * to <tt>true</tt> grants threads access in FIFO order. Fairness
- * generally decreases throughput but reduces variability and avoids
- * starvation.
- *
- * <p>This class and its iterator implement all of the
- * <em>optional</em> methods of the {@link Collection} and {@link
- * Iterator} interfaces.
- *
- * <p>This class is a member of the
- * <a href="{@docRoot}/../technotes/guides/collections/index.html">
- * Java Collections Framework</a>.
- *
- * @since 1.5
- * @author Doug Lea
- */
-public class SynchronousQueue extends AbstractQueue
- implements BlockingQueue, java.io.Serializable {
- private static final long serialVersionUID = -3223113410248163686L;
-
- /*
- This implementation divides actions into two cases for puts:
-
- * An arriving producer that does not already have a waiting consumer
- creates a node holding item, and then waits for a consumer to take it.
- * An arriving producer that does already have a waiting consumer fills
- the slot node created by the consumer, and notifies it to continue.
-
- And symmetrically, two for takes:
-
- * An arriving consumer that does not already have a waiting producer
- creates an empty slot node, and then waits for a producer to fill it.
- * An arriving consumer that does already have a waiting producer takes
- item from the node created by the producer, and notifies it to continue.
-
- When a put or take waiting for the actions of its counterpart
- aborts due to interruption or timeout, it marks the node
- it created as "CANCELLED", which causes its counterpart to retry
- the entire put or take sequence.
-
- This requires keeping two simple queues, waitingProducers and
- waitingConsumers. Each of these can be FIFO (preserves fairness)
- or LIFO (improves throughput).
- */
-
- /** Lock protecting both wait queues */
- private final ReentrantLock qlock;
- /** Queue holding waiting puts */
- private final WaitQueue waitingProducers;
- /** Queue holding waiting takes */
- private final WaitQueue waitingConsumers;
-
- /**
- * Creates a <tt>SynchronousQueue</tt> with nonfair access policy.
- */
- public SynchronousQueue() {
- this(false);
- }
-
- /**
- * Creates a <tt>SynchronousQueue</tt> with specified fairness policy.
- * @param fair if true, threads contend in FIFO order for access;
- * otherwise the order is unspecified.
- */
- public SynchronousQueue(boolean fair) {
- if (fair) {
- qlock = new ReentrantLock(true);
- waitingProducers = new FifoWaitQueue();
- waitingConsumers = new FifoWaitQueue();
- }
- else {
- qlock = new ReentrantLock();
- waitingProducers = new LifoWaitQueue();
- waitingConsumers = new LifoWaitQueue();
- }
- }
-
- /**
- * Queue to hold waiting puts/takes; specialized to Fifo/Lifo below.
- * These queues have all transient fields, but are serializable
- * in order to recover fairness settings when deserialized.
- */
- static abstract class WaitQueue implements java.io.Serializable {
- /** Creates, adds, and returns node for x. */
- abstract Node enq(Object x);
- /** Removes and returns node, or null if empty. */
- abstract Node deq();
- /** Removes a cancelled node to avoid garbage retention. */
- abstract void unlink(Node node);
- /** Returns true if a cancelled node might be on queue. */
- abstract boolean shouldUnlink(Node node);
- }
-
- /**
- * FIFO queue to hold waiting puts/takes.
- */
- static final class FifoWaitQueue extends WaitQueue implements java.io.Serializable {
- private static final long serialVersionUID = -3623113410248163686L;
- private transient Node head;
- private transient Node last;
-
- Node enq(Object x) {
- Node p = new Node(x);
- if (last == null)
- last = head = p;
- else
- last = last.next = p;
- return p;
- }
-
- Node deq() {
- Node p = head;
- if (p != null) {
- if ((head = p.next) == null)
- last = null;
- p.next = null;
- }
- return p;
- }
-
- boolean shouldUnlink(Node node) {
- return (node == last || node.next != null);
- }
-
- void unlink(Node node) {
- Node p = head;
- Node trail = null;
- while (p != null) {
- if (p == node) {
- Node next = p.next;
- if (trail == null)
- head = next;
- else
- trail.next = next;
- if (last == node)
- last = trail;
- break;
- }
- trail = p;
- p = p.next;
- }
- }
- }
-
- /**
- * LIFO queue to hold waiting puts/takes.
- */
- static final class LifoWaitQueue extends WaitQueue implements java.io.Serializable {
- private static final long serialVersionUID = -3633113410248163686L;
- private transient Node head;
-
- Node enq(Object x) {
- return head = new Node(x, head);
- }
-
- Node deq() {
- Node p = head;
- if (p != null) {
- head = p.next;
- p.next = null;
- }
- return p;
- }
-
- boolean shouldUnlink(Node node) {
- // Return false if already dequeued or is bottom node (in which
- // case we might retain at most one garbage node)
- return (node == head || node.next != null);
- }
-
- void unlink(Node node) {
- Node p = head;
- Node trail = null;
- while (p != null) {
- if (p == node) {
- Node next = p.next;
- if (trail == null)
- head = next;
- else
- trail.next = next;
- break;
- }
- trail = p;
- p = p.next;
- }
- }
- }
-
- /**
- * Unlinks the given node from consumer queue. Called by cancelled
- * (timeout, interrupt) waiters to avoid garbage retention in the
- * absence of producers.
- */
- private void unlinkCancelledConsumer(Node node) {
- // Use a form of double-check to avoid unnecessary locking and
- // traversal. The first check outside lock might
- // conservatively report true.
- if (waitingConsumers.shouldUnlink(node)) {
- qlock.lock();
- try {
- if (waitingConsumers.shouldUnlink(node))
- waitingConsumers.unlink(node);
- } finally {
- qlock.unlock();
- }
- }
- }
-
- /**
- * Unlinks the given node from producer queue. Symmetric
- * to unlinkCancelledConsumer.
- */
- private void unlinkCancelledProducer(Node node) {
- if (waitingProducers.shouldUnlink(node)) {
- qlock.lock();
- try {
- if (waitingProducers.shouldUnlink(node))
- waitingProducers.unlink(node);
- } finally {
- qlock.unlock();
- }
- }
- }
-
- /**
- * Nodes each maintain an item and handle waits and signals for
- * getting and setting it. The class extends
- * AbstractQueuedSynchronizer to manage blocking, using AQS state
- * 0 for waiting, 1 for ack, -1 for cancelled.
- */
- static final class Node implements java.io.Serializable {
- private static final long serialVersionUID = -3223113410248163686L;
-
- /** Synchronization state value representing that node acked */
- private static final int ACK = 1;
- /** Synchronization state value representing that node cancelled */
- private static final int CANCEL = -1;
-
- int state = 0;
-
- /** The item being transferred */
- Object item;
- /** Next node in wait queue */
- Node next;
-
- /** Creates a node with initial item */
- Node(Object x) { item = x; }
-
- /** Creates a node with initial item and next */
- Node(Object x, Node n) { item = x; next = n; }
-
- /**
- * Takes item and nulls out field (for sake of GC)
- *
- * PRE: lock owned
- */
- private Object extract() {
- Object x = item;
- item = null;
- return x;
- }
-
- /**
- * Tries to cancel on interrupt; if so rethrowing,
- * else setting interrupt state
- *
- * PRE: lock owned
- */
- private void checkCancellationOnInterrupt(InterruptedException ie)
- throws InterruptedException
- {
- if (state == 0) {
- state = CANCEL;
- notify();
- throw ie;
- }
- Thread.currentThread().interrupt();
- }
-
- /**
- * Fills in the slot created by the consumer and signal consumer to
- * continue.
- */
- synchronized boolean setItem(Object x) {
- if (state != 0) return false;
- item = x;
- state = ACK;
- notify();
- return true;
- }
-
- /**
- * Removes item from slot created by producer and signal producer
- * to continue.
- */
- synchronized Object getItem() {
- if (state != 0) return null;
- state = ACK;
- notify();
- return extract();
- }
-
- /**
- * Waits for a consumer to take item placed by producer.
- */
- synchronized void waitForTake() throws InterruptedException {
- try {
- while (state == 0) wait();
- } catch (InterruptedException ie) {
- checkCancellationOnInterrupt(ie);
- }
- }
-
- /**
- * Waits for a producer to put item placed by consumer.
- */
- synchronized Object waitForPut() throws InterruptedException {
- try {
- while (state == 0) wait();
- } catch (InterruptedException ie) {
- checkCancellationOnInterrupt(ie);
- }
- return extract();
- }
-
- private boolean attempt(long nanos) throws InterruptedException {
- if (state != 0) return true;
- if (nanos <= 0) {
- state = CANCEL;
- notify();
- return false;
- }
- long deadline = Utils.nanoTime() + nanos;
- while (true) {
- TimeUnit.NANOSECONDS.timedWait(this, nanos);
- if (state != 0) return true;
- nanos = deadline - Utils.nanoTime();
- if (nanos <= 0) {
- state = CANCEL;
- notify();
- return false;
- }
- }
- }
-
- /**
- * Waits for a consumer to take item placed by producer or time out.
- */
- synchronized boolean waitForTake(long nanos) throws InterruptedException {
- try {
- if (!attempt(nanos)) return false;
- } catch (InterruptedException ie) {
- checkCancellationOnInterrupt(ie);
- }
- return true;
- }
-
- /**
- * Waits for a producer to put item placed by consumer, or time out.
- */
- synchronized Object waitForPut(long nanos) throws InterruptedException {
- try {
- if (!attempt(nanos)) return null;
- } catch (InterruptedException ie) {
- checkCancellationOnInterrupt(ie);
- }
- return extract();
- }
- }
-
- /**
- * Adds the specified element to this queue, waiting if necessary for
- * another thread to receive it.
- *
- * @throws InterruptedException {@inheritDoc}
- * @throws NullPointerException {@inheritDoc}
- */
- public void put(Object e) throws InterruptedException {
- if (e == null) throw new NullPointerException();
- final ReentrantLock qlock = this.qlock;
-
- for (;;) {
- Node node;
- boolean mustWait;
- if (Thread.interrupted()) throw new InterruptedException();
- qlock.lock();
- try {
- node = waitingConsumers.deq();
- if ( (mustWait = (node == null)) )
- node = waitingProducers.enq(e);
- } finally {
- qlock.unlock();
- }
-
- if (mustWait) {
- try {
- node.waitForTake();
- return;
- } catch (InterruptedException ex) {
- unlinkCancelledProducer(node);
- throw ex;
- }
- }
-
- else if (node.setItem(e))
- return;
-
- // else consumer cancelled, so retry
- }
- }
-
- /**
- * Inserts the specified element into this queue, waiting if necessary
- * up to the specified wait time for another thread to receive it.
- *
- * @return <tt>true</tt> if successful, or <tt>false</tt> if the
- * specified waiting time elapses before a consumer appears.
- * @throws InterruptedException {@inheritDoc}
- * @throws NullPointerException {@inheritDoc}
- */
- public boolean offer(Object e, long timeout, TimeUnit unit) throws InterruptedException {
- if (e == null) throw new NullPointerException();
- long nanos = unit.toNanos(timeout);
- final ReentrantLock qlock = this.qlock;
- for (;;) {
- Node node;
- boolean mustWait;
- if (Thread.interrupted()) throw new InterruptedException();
- qlock.lock();
- try {
- node = waitingConsumers.deq();
- if ( (mustWait = (node == null)) )
- node = waitingProducers.enq(e);
- } finally {
- qlock.unlock();
- }
-
- if (mustWait) {
- try {
- boolean x = node.waitForTake(nanos);
- if (!x)
- unlinkCancelledProducer(node);
- return x;
- } catch (InterruptedException ex) {
- unlinkCancelledProducer(node);
- throw ex;
- }
- }
-
- else if (node.setItem(e))
- return true;
-
- // else consumer cancelled, so retry
- }
- }
-
- /**
- * Retrieves and removes the head of this queue, waiting if necessary
- * for another thread to insert it.
- *
- * @return the head of this queue
- * @throws InterruptedException {@inheritDoc}
- */
- public Object take() throws InterruptedException {
- final ReentrantLock qlock = this.qlock;
- for (;;) {
- Node node;
- boolean mustWait;
-
- if (Thread.interrupted()) throw new InterruptedException();
- qlock.lock();
- try {
- node = waitingProducers.deq();
- if ( (mustWait = (node == null)) )
- node = waitingConsumers.enq(null);
- } finally {
- qlock.unlock();
- }
-
- if (mustWait) {
- try {
- Object x = node.waitForPut();
- return (Object)x;
- } catch (InterruptedException ex) {
- unlinkCancelledConsumer(node);
- throw ex;
- }
- }
- else {
- Object x = node.getItem();
- if (x != null)
- return (Object)x;
- // else cancelled, so retry
- }
- }
- }
-
- /**
- * Retrieves and removes the head of this queue, waiting
- * if necessary up to the specified wait time, for another thread
- * to insert it.
- *
- * @return the head of this queue, or <tt>null</tt> if the
- * specified waiting time elapses before an element is present.
- * @throws InterruptedException {@inheritDoc}
- */
- public Object poll(long timeout, TimeUnit unit) throws InterruptedException {
- long nanos = unit.toNanos(timeout);
- final ReentrantLock qlock = this.qlock;
-
- for (;;) {
- Node node;
- boolean mustWait;
-
- if (Thread.interrupted()) throw new InterruptedException();
- qlock.lock();
- try {
- node = waitingProducers.deq();
- if ( (mustWait = (node == null)) )
- node = waitingConsumers.enq(null);
- } finally {
- qlock.unlock();
- }
-
- if (mustWait) {
- try {
- Object x = node.waitForPut(nanos);
- if (x == null)
- unlinkCancelledConsumer(node);
- return (Object)x;
- } catch (InterruptedException ex) {
- unlinkCancelledConsumer(node);
- throw ex;
- }
- }
- else {
- Object x = node.getItem();
- if (x != null)
- return (Object)x;
- // else cancelled, so retry
- }
- }
- }
-
- // Untimed nonblocking versions
-
- /**
- * Inserts the specified element into this queue, if another thread is
- * waiting to receive it.
- *
- * @param e the element to add
- * @return <tt>true</tt> if the element was added to this queue, else
- * <tt>false</tt>
- * @throws NullPointerException if the specified element is null
- */
- public boolean offer(Object e) {
- if (e == null) throw new NullPointerException();
- final ReentrantLock qlock = this.qlock;
-
- for (;;) {
- Node node;
- qlock.lock();
- try {
- node = waitingConsumers.deq();
- } finally {
- qlock.unlock();
- }
- if (node == null)
- return false;
-
- else if (node.setItem(e))
- return true;
- // else retry
- }
- }
-
- /**
- * Retrieves and removes the head of this queue, if another thread
- * is currently making an element available.
- *
- * @return the head of this queue, or <tt>null</tt> if no
- * element is available.
- */
- public Object poll() {
- final ReentrantLock qlock = this.qlock;
- for (;;) {
- Node node;
- qlock.lock();
- try {
- node = waitingProducers.deq();
- } finally {
- qlock.unlock();
- }
- if (node == null)
- return null;
-
- else {
- Object x = node.getItem();
- if (x != null)
- return (Object)x;
- // else retry
- }
- }
- }
-
- /**
- * Always returns <tt>true</tt>.
- * A <tt>SynchronousQueue</tt> has no internal capacity.
- *
- * @return <tt>true</tt>
- */
- public boolean isEmpty() {
- return true;
- }
-
- /**
- * Always returns zero.
- * A <tt>SynchronousQueue</tt> has no internal capacity.
- *
- * @return zero
- */
- public int size() {
- return 0;
- }
-
- /**
- * Always returns zero.
- * A <tt>SynchronousQueue</tt> has no internal capacity.
- *
- * @return zero
- */
- public int remainingCapacity() {
- return 0;
- }
-
- /**
- * Does nothing.
- * A <tt>SynchronousQueue</tt> has no internal capacity.
- */
- public void clear() {}
-
- /**
- * Always returns <tt>false</tt>.
- * A <tt>SynchronousQueue</tt> has no internal capacity.
- *
- * @param o object to be checked for containment in this queue
- * @return <tt>false</tt>
- */
- public boolean contains(Object o) {
- return false;
- }
-
- /**
- * Always returns <tt>false</tt>.
- * A <tt>SynchronousQueue</tt> has no internal capacity.
- *
- * @param o the element to remove
- * @return <tt>false</tt>
- */
- public boolean remove(Object o) {
- return false;
- }
-
- /**
- * Returns <tt>false</tt> unless the given collection is empty.
- * A <tt>SynchronousQueue</tt> has no internal capacity.
- *
- * @param c the collection
- * @return <tt>false</tt> unless the given collection is empty
- * @throws NullPointerException if the specified collection is null
- */
- public boolean containsAll(Collection c) {
- return c.isEmpty();
- }
-
- /**
- * Always returns <tt>false</tt>.
- * A <tt>SynchronousQueue</tt> has no internal capacity.
- *
- * @param c the collection
- * @return <tt>false</tt>
- */
- public boolean removeAll(Collection c) {
- return false;
- }
-
- /**
- * Always returns <tt>false</tt>.
- * A <tt>SynchronousQueue</tt> has no internal capacity.
- *
- * @param c the collection
- * @return <tt>false</tt>
- */
- public boolean retainAll(Collection c) {
- return false;
- }
-
- /**
- * Always returns <tt>null</tt>.
- * A <tt>SynchronousQueue</tt> does not return elements
- * unless actively waited on.
- *
- * @return <tt>null</tt>
- */
- public Object peek() {
- return null;
- }
-
-
- static class EmptyIterator implements Iterator {
- public boolean hasNext() {
- return false;
- }
- public Object next() {
- throw new NoSuchElementException();
- }
- public void remove() {
- throw new IllegalStateException();
- }
- }
-
- /**
- * Returns an empty iterator in which <tt>hasNext</tt> always returns
- * <tt>false</tt>.
- *
- * @return an empty iterator
- */
- public Iterator iterator() {
- return new EmptyIterator();
- }
-
-
- /**
- * Returns a zero-length array.
- * @return a zero-length array
- */
- public Object[] toArray() {
- return new Object[0];
- }
-
- /**
- * Sets the zeroeth element of the specified array to <tt>null</tt>
- * (if the array has non-zero length) and returns it.
- *
- * @param a the array
- * @return the specified array
- * @throws NullPointerException if the specified array is null
- */
- public Object[] toArray(Object[] a) {
- if (a.length > 0)
- a[0] = null;
- return a;
- }
-
- /**
- * @throws UnsupportedOperationException {@inheritDoc}
- * @throws ClassCastException {@inheritDoc}
- * @throws NullPointerException {@inheritDoc}
- * @throws IllegalArgumentException {@inheritDoc}
- */
- public int drainTo(Collection c) {
- if (c == null)
- throw new NullPointerException();
- if (c == this)
- throw new IllegalArgumentException();
- int n = 0;
- Object e;
- while ( (e = poll()) != null) {
- c.add(e);
- ++n;
- }
- return n;
- }
-
- /**
- * @throws UnsupportedOperationException {@inheritDoc}
- * @throws ClassCastException {@inheritDoc}
- * @throws NullPointerException {@inheritDoc}
- * @throws IllegalArgumentException {@inheritDoc}
- */
- public int drainTo(Collection c, int maxElements) {
- if (c == null)
- throw new NullPointerException();
- if (c == this)
- throw new IllegalArgumentException();
- int n = 0;
- Object e;
- while (n < maxElements && (e = poll()) != null) {
- c.add(e);
- ++n;
- }
- return n;
- }
-}
diff --git a/src/actors/scala/actors/threadpool/ThreadFactory.java b/src/actors/scala/actors/threadpool/ThreadFactory.java
deleted file mode 100644
index ed6e90ccaa..0000000000
--- a/src/actors/scala/actors/threadpool/ThreadFactory.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
- */
-
-package scala.actors.threadpool;
-
-/**
- * An object that creates new threads on demand. Using thread factories
- * removes hardwiring of calls to {@link Thread#Thread(Runnable) new Thread},
- * enabling applications to use special thread subclasses, priorities, etc.
- *
- * <p>
- * The simplest implementation of this interface is just:
- * <pre>
- * class SimpleThreadFactory implements ThreadFactory {
- * public Thread newThread(Runnable r) {
- * return new Thread(r);
- * }
- * }
- * </pre>
- *
- * The {@link Executors#defaultThreadFactory} method provides a more
- * useful simple implementation, that sets the created thread context
- * to known values before returning it.
- * @since 1.5
- * @author Doug Lea
- */
-public interface ThreadFactory {
-
- /**
- * Constructs a new {@code Thread}. Implementations may also initialize
- * priority, name, daemon status, {@code ThreadGroup}, etc.
- *
- * @param r a runnable to be executed by new thread instance
- * @return constructed thread, or {@code null} if the request to
- * create a thread is rejected
- */
- Thread newThread(Runnable r);
-}
diff --git a/src/actors/scala/actors/threadpool/ThreadPoolExecutor.java b/src/actors/scala/actors/threadpool/ThreadPoolExecutor.java
deleted file mode 100644
index 11e35b034c..0000000000
--- a/src/actors/scala/actors/threadpool/ThreadPoolExecutor.java
+++ /dev/null
@@ -1,1968 +0,0 @@
-/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
- */
-
-package scala.actors.threadpool;
-import scala.actors.threadpool.locks.*;
-import scala.actors.threadpool.helpers.Utils;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Iterator;
-import java.util.ArrayList;
-import java.util.ConcurrentModificationException;
-
-/**
- * An {@link ExecutorService} that executes each submitted task using
- * one of possibly several pooled threads, normally configured
- * using {@link Executors} factory methods.
- *
- * <p>Thread pools address two different problems: they usually
- * provide improved performance when executing large numbers of
- * asynchronous tasks, due to reduced per-task invocation overhead,
- * and they provide a means of bounding and managing the resources,
- * including threads, consumed when executing a collection of tasks.
- * Each {@code ThreadPoolExecutor} also maintains some basic
- * statistics, such as the number of completed tasks.
- *
- * <p>To be useful across a wide range of contexts, this class
- * provides many adjustable parameters and extensibility
- * hooks. However, programmers are urged to use the more convenient
- * {@link Executors} factory methods {@link
- * Executors#newCachedThreadPool} (unbounded thread pool, with
- * automatic thread reclamation), {@link Executors#newFixedThreadPool}
- * (fixed size thread pool) and {@link
- * Executors#newSingleThreadExecutor} (single background thread), that
- * preconfigure settings for the most common usage
- * scenarios. Otherwise, use the following guide when manually
- * configuring and tuning this class:
- *
- * <dl>
- *
- * <dt>Core and maximum pool sizes</dt>
- *
- * <dd>A {@code ThreadPoolExecutor} will automatically adjust the
- * pool size (see {@link #getPoolSize})
- * according to the bounds set by
- * corePoolSize (see {@link #getCorePoolSize}) and
- * maximumPoolSize (see {@link #getMaximumPoolSize}).
- *
- * When a new task is submitted in method {@link #execute}, and fewer
- * than corePoolSize threads are running, a new thread is created to
- * handle the request, even if other worker threads are idle. If
- * there are more than corePoolSize but less than maximumPoolSize
- * threads running, a new thread will be created only if the queue is
- * full. By setting corePoolSize and maximumPoolSize the same, you
- * create a fixed-size thread pool. By setting maximumPoolSize to an
- * essentially unbounded value such as {@code Integer.MAX_VALUE}, you
- * allow the pool to accommodate an arbitrary number of concurrent
- * tasks. Most typically, core and maximum pool sizes are set only
- * upon construction, but they may also be changed dynamically using
- * {@link #setCorePoolSize} and {@link #setMaximumPoolSize}. </dd>
- *
- * <dt>On-demand construction</dt>
- *
- * <dd> By default, even core threads are initially created and
- * started only when new tasks arrive, but this can be overridden
- * dynamically using method {@link #prestartCoreThread} or {@link
- * #prestartAllCoreThreads}. You probably want to prestart threads if
- * you construct the pool with a non-empty queue. </dd>
- *
- * <dt>Creating new threads</dt>
- *
- * <dd>New threads are created using a {@link ThreadFactory}. If not
- * otherwise specified, a {@link Executors#defaultThreadFactory} is
- * used, that creates threads to all be in the same {@link
- * ThreadGroup} and with the same {@code NORM_PRIORITY} priority and
- * non-daemon status. By supplying a different ThreadFactory, you can
- * alter the thread's name, thread group, priority, daemon status,
- * etc. If a {@code ThreadFactory} fails to create a thread when asked
- * by returning null from {@code newThread}, the executor will
- * continue, but might not be able to execute any tasks. Threads
- * should possess the "modifyThread" {@code RuntimePermission}. If
- * worker threads or other threads using the pool do not possess this
- * permission, service may be degraded: configuration changes may not
- * take effect in a timely manner, and a shutdown pool may remain in a
- * state in which termination is possible but not completed.</dd>
- *
- * <dt>Keep-alive times</dt>
- *
- * <dd>If the pool currently has more than corePoolSize threads,
- * excess threads will be terminated if they have been idle for more
- * than the keepAliveTime (see {@link #getKeepAliveTime}). This
- * provides a means of reducing resource consumption when the pool is
- * not being actively used. If the pool becomes more active later, new
- * threads will be constructed. This parameter can also be changed
- * dynamically using method {@link #setKeepAliveTime}. Using a value
- * of {@code Long.MAX_VALUE} {@link TimeUnit#NANOSECONDS} effectively
- * disables idle threads from ever terminating prior to shut down. By
- * default, the keep-alive policy applies only when there are more
- * than corePoolSizeThreads. But method {@link
- * #allowCoreThreadTimeOut(boolean)} can be used to apply this
- * time-out policy to core threads as well, so long as the
- * keepAliveTime value is non-zero. </dd>
- *
- * <dt>Queuing</dt>
- *
- * <dd>Any {@link BlockingQueue} may be used to transfer and hold
- * submitted tasks. The use of this queue interacts with pool sizing:
- *
- * <ul>
- *
- * <li> If fewer than corePoolSize threads are running, the Executor
- * always prefers adding a new thread
- * rather than queuing.</li>
- *
- * <li> If corePoolSize or more threads are running, the Executor
- * always prefers queuing a request rather than adding a new
- * thread.</li>
- *
- * <li> If a request cannot be queued, a new thread is created unless
- * this would exceed maximumPoolSize, in which case, the task will be
- * rejected.</li>
- *
- * </ul>
- *
- * There are three general strategies for queuing:
- * <ol>
- *
- * <li> <em> Direct handoffs.</em> A good default choice for a work
- * queue is a {@link SynchronousQueue} that hands off tasks to threads
- * without otherwise holding them. Here, an attempt to queue a task
- * will fail if no threads are immediately available to run it, so a
- * new thread will be constructed. This policy avoids lockups when
- * handling sets of requests that might have internal dependencies.
- * Direct handoffs generally require unbounded maximumPoolSizes to
- * avoid rejection of new submitted tasks. This in turn admits the
- * possibility of unbounded thread growth when commands continue to
- * arrive on average faster than they can be processed. </li>
- *
- * <li><em> Unbounded queues.</em> Using an unbounded queue (for
- * example a {@link LinkedBlockingQueue} without a predefined
- * capacity) will cause new tasks to wait in the queue when all
- * corePoolSize threads are busy. Thus, no more than corePoolSize
- * threads will ever be created. (And the value of the maximumPoolSize
- * therefore doesn't have any effect.) This may be appropriate when
- * each task is completely independent of others, so tasks cannot
- * affect each others execution; for example, in a web page server.
- * While this style of queuing can be useful in smoothing out
- * transient bursts of requests, it admits the possibility of
- * unbounded work queue growth when commands continue to arrive on
- * average faster than they can be processed. </li>
- *
- * <li><em>Bounded queues.</em> A bounded queue (for example, an
- * {@link ArrayBlockingQueue}) helps prevent resource exhaustion when
- * used with finite maximumPoolSizes, but can be more difficult to
- * tune and control. Queue sizes and maximum pool sizes may be traded
- * off for each other: Using large queues and small pools minimizes
- * CPU usage, OS resources, and context-switching overhead, but can
- * lead to artificially low throughput. If tasks frequently block (for
- * example if they are I/O bound), a system may be able to schedule
- * time for more threads than you otherwise allow. Use of small queues
- * generally requires larger pool sizes, which keeps CPUs busier but
- * may encounter unacceptable scheduling overhead, which also
- * decreases throughput. </li>
- *
- * </ol>
- *
- * </dd>
- *
- * <dt>Rejected tasks</dt>
- *
- * <dd> New tasks submitted in method {@link #execute} will be
- * <em>rejected</em> when the Executor has been shut down, and also
- * when the Executor uses finite bounds for both maximum threads and
- * work queue capacity, and is saturated. In either case, the {@code
- * execute} method invokes the {@link
- * RejectedExecutionHandler#rejectedExecution} method of its {@link
- * RejectedExecutionHandler}. Four predefined handler policies are
- * provided:
- *
- * <ol>
- *
- * <li> In the default {@link ThreadPoolExecutor.AbortPolicy}, the
- * handler throws a runtime {@link RejectedExecutionException} upon
- * rejection. </li>
- *
- * <li> In {@link ThreadPoolExecutor.CallerRunsPolicy}, the thread
- * that invokes {@code execute} itself runs the task. This provides a
- * simple feedback control mechanism that will slow down the rate that
- * new tasks are submitted. </li>
- *
- * <li> In {@link ThreadPoolExecutor.DiscardPolicy}, a task that
- * cannot be executed is simply dropped. </li>
- *
- * <li>In {@link ThreadPoolExecutor.DiscardOldestPolicy}, if the
- * executor is not shut down, the task at the head of the work queue
- * is dropped, and then execution is retried (which can fail again,
- * causing this to be repeated.) </li>
- *
- * </ol>
- *
- * It is possible to define and use other kinds of {@link
- * RejectedExecutionHandler} classes. Doing so requires some care
- * especially when policies are designed to work only under particular
- * capacity or queuing policies. </dd>
- *
- * <dt>Hook methods</dt>
- *
- * <dd>This class provides {@code protected} overridable {@link
- * #beforeExecute} and {@link #afterExecute} methods that are called
- * before and after execution of each task. These can be used to
- * manipulate the execution environment; for example, reinitializing
- * ThreadLocals, gathering statistics, or adding log
- * entries. Additionally, method {@link #terminated} can be overridden
- * to perform any special processing that needs to be done once the
- * Executor has fully terminated.
- *
- * <p>If hook or callback methods throw exceptions, internal worker
- * threads may in turn fail and abruptly terminate.</dd>
- *
- * <dt>Queue maintenance</dt>
- *
- * <dd> Method {@link #getQueue} allows access to the work queue for
- * purposes of monitoring and debugging. Use of this method for any
- * other purpose is strongly discouraged. Two supplied methods,
- * {@link #remove} and {@link #purge} are available to assist in
- * storage reclamation when large numbers of queued tasks become
- * cancelled.</dd>
- *
- * <dt>Finalization</dt>
- *
- * <dd> A pool that is no longer referenced in a program <em>AND</em>
- * has no remaining threads will be {@code shutdown} automatically. If
- * you would like to ensure that unreferenced pools are reclaimed even
- * if users forget to call {@link #shutdown}, then you must arrange
- * that unused threads eventually die, by setting appropriate
- * keep-alive times, using a lower bound of zero core threads and/or
- * setting {@link #allowCoreThreadTimeOut(boolean)}. </dd>
- *
- * </dl>
- *
- * <p> <b>Extension example</b>. Most extensions of this class
- * override one or more of the protected hook methods. For example,
- * here is a subclass that adds a simple pause/resume feature:
- *
- * <pre> {@code
- * class PausableThreadPoolExecutor extends ThreadPoolExecutor {
- * private boolean isPaused;
- * private ReentrantLock pauseLock = new ReentrantLock();
- * private Condition unpaused = pauseLock.newCondition();
- *
- * public PausableThreadPoolExecutor(...) { super(...); }
- *
- * protected void beforeExecute(Thread t, Runnable r) {
- * super.beforeExecute(t, r);
- * pauseLock.lock();
- * try {
- * while (isPaused) unpaused.await();
- * } catch (InterruptedException ie) {
- * t.interrupt();
- * } finally {
- * pauseLock.unlock();
- * }
- * }
- *
- * public void pause() {
- * pauseLock.lock();
- * try {
- * isPaused = true;
- * } finally {
- * pauseLock.unlock();
- * }
- * }
- *
- * public void resume() {
- * pauseLock.lock();
- * try {
- * isPaused = false;
- * unpaused.signalAll();
- * } finally {
- * pauseLock.unlock();
- * }
- * }
- * }}</pre>
- *
- * @since 1.5
- * @author Doug Lea
- */
-public class ThreadPoolExecutor extends AbstractExecutorService {
- /**
- * The main pool control state, ctl, is an atomic integer packing
- * two conceptual fields
- * workerCount, indicating the effective number of threads
- * runState, indicating whether running, shutting down etc
- *
- * In order to pack them into one int, we limit workerCount to
- * (2^29)-1 (about 500 million) threads rather than (2^31)-1 (2
- * billion) otherwise representable. If this is ever an issue in
- * the future, the variable can be changed to be an AtomicLong,
- * and the shift/mask constants below adjusted. But until the need
- * arises, this code is a bit faster and simpler using an int.
- *
- * The workerCount is the number of workers that have been
- * permitted to start and not permitted to stop. The value may be
- * transiently different from the actual number of live threads,
- * for example when a ThreadFactory fails to create a thread when
- * asked, and when exiting threads are still performing
- * bookkeeping before terminating. The user-visible pool size is
- * reported as the current size of the workers set.
- *
- * The runState provides the main lifecyle control, taking on values:
- *
- * RUNNING: Accept new tasks and process queued tasks
- * SHUTDOWN: Don't accept new tasks, but process queued tasks
- * STOP: Don't accept new tasks, don't process queued tasks,
- * and interrupt in-progress tasks
- * TIDYING: All tasks have terminated, workerCount is zero,
- * the thread transitioning to state TIDYING
- * will run the terminated() hook method
- * TERMINATED: terminated() has completed
- *
- * The numerical order among these values matters, to allow
- * ordered comparisons. The runState monotonically increases over
- * time, but need not hit each state. The transitions are:
- *
- * RUNNING -> SHUTDOWN
- * On invocation of shutdown(), perhaps implicitly in finalize()
- * (RUNNING or SHUTDOWN) -> STOP
- * On invocation of shutdownNow()
- * SHUTDOWN -> TIDYING
- * When both queue and pool are empty
- * STOP -> TIDYING
- * When pool is empty
- * TIDYING -> TERMINATED
- * When the terminated() hook method has completed
- *
- * Threads waiting in awaitTermination() will return when the
- * state reaches TERMINATED.
- *
- * Detecting the transition from SHUTDOWN to TIDYING is less
- * straightforward than you'd like because the queue may become
- * empty after non-empty and vice versa during SHUTDOWN state, but
- * we can only terminate if, after seeing that it is empty, we see
- * that workerCount is 0 (which sometimes entails a recheck -- see
- * below).
- */
- private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
- private static final int COUNT_BITS = 29; // Integer.SIZE - 3;
- private static final int CAPACITY = (1 << COUNT_BITS) - 1;
-
- // runState is stored in the high-order bits
- private static final int RUNNING = -1 << COUNT_BITS;
- private static final int SHUTDOWN = 0 << COUNT_BITS;
- private static final int STOP = 1 << COUNT_BITS;
- private static final int TIDYING = 2 << COUNT_BITS;
- private static final int TERMINATED = 3 << COUNT_BITS;
-
- // Packing and unpacking ctl
- private static int runStateOf(int c) { return c & ~CAPACITY; }
- private static int workerCountOf(int c) { return c & CAPACITY; }
- private static int ctlOf(int rs, int wc) { return rs | wc; }
-
- /*
- * Bit field accessors that don't require unpacking ctl.
- * These depend on the bit layout and on workerCount being never negative.
- */
-
- private static boolean runStateLessThan(int c, int s) {
- return c < s;
- }
-
- private static boolean runStateAtLeast(int c, int s) {
- return c >= s;
- }
-
- private static boolean isRunning(int c) {
- return c < SHUTDOWN;
- }
-
- /**
- * Attempt to CAS-increment the workerCount field of ctl.
- */
- private boolean compareAndIncrementWorkerCount(int expect) {
- return ctl.compareAndSet(expect, expect + 1);
- }
-
- /**
- * Attempt to CAS-decrement the workerCount field of ctl.
- */
- private boolean compareAndDecrementWorkerCount(int expect) {
- return ctl.compareAndSet(expect, expect - 1);
- }
-
- /**
- * Decrements the workerCount field of ctl. This is called only on
- * abrupt termination of a thread (see processWorkerExit). Other
- * decrements are performed within getTask.
- */
- private void decrementWorkerCount() {
- do {} while (! compareAndDecrementWorkerCount(ctl.get()));
- }
-
- /**
- * The queue used for holding tasks and handing off to worker
- * threads. We do not require that workQueue.poll() returning
- * null necessarily means that workQueue.isEmpty(), so rely
- * solely on isEmpty to see if the queue is empty (which we must
- * do for example when deciding whether to transition from
- * SHUTDOWN to TIDYING). This accommodates special-purpose
- * queues such as DelayQueues for which poll() is allowed to
- * return null even if it may later return non-null when delays
- * expire.
- */
- private final BlockingQueue workQueue;
-
- // TODO: DK: mainLock is used in lock(); try { ... } finally { unlock(); }
- // Consider replacing with synchronized {} if performance reasons exist
- /**
- * Lock held on access to workers set and related bookkeeping.
- * While we could use a concurrent set of some sort, it turns out
- * to be generally preferable to use a lock. Among the reasons is
- * that this serializes interruptIdleWorkers, which avoids
- * unnecessary interrupt storms, especially during shutdown.
- * Otherwise exiting threads would concurrently interrupt those
- * that have not yet interrupted. It also simplifies some of the
- * associated statistics bookkeeping of largestPoolSize etc. We
- * also hold mainLock on shutdown and shutdownNow, for the sake of
- * ensuring workers set is stable while separately checking
- * permission to interrupt and actually interrupting.
- */
- public final ReentrantLock mainLock = new ReentrantLock();
-
- /**
- * Set containing all worker threads in pool. Accessed only when
- * holding mainLock.
- */
- public final HashSet workers = new HashSet();
-
- /**
- * Wait condition to support awaitTermination
- */
- private final Condition termination = mainLock.newCondition();
-
- /**
- * Tracks largest attained pool size. Accessed only under
- * mainLock.
- */
- private int largestPoolSize;
-
- /**
- * Counter for completed tasks. Updated only on termination of
- * worker threads. Accessed only under mainLock.
- */
- private long completedTaskCount;
-
- /*
- * All user control parameters are declared as volatiles so that
- * ongoing actions are based on freshest values, but without need
- * for locking, since no internal invariants depend on them
- * changing synchronously with respect to other actions.
- */
-
- /**
- * Factory for new threads. All threads are created using this
- * factory (via method addWorker). All callers must be prepared
- * for addWorker to fail, which may reflect a system or user's
- * policy limiting the number of threads. Even though it is not
- * treated as an error, failure to create threads may result in
- * new tasks being rejected or existing ones remaining stuck in
- * the queue. On the other hand, no special precautions exist to
- * handle OutOfMemoryErrors that might be thrown while trying to
- * create threads, since there is generally no recourse from
- * within this class.
- */
- private volatile ThreadFactory threadFactory;
-
- /**
- * Handler called when saturated or shutdown in execute.
- */
- private volatile RejectedExecutionHandler handler;
-
- /**
- * Timeout in nanoseconds for idle threads waiting for work.
- * Threads use this timeout when there are more than corePoolSize
- * present or if allowCoreThreadTimeOut. Otherwise they wait
- * forever for new work.
- */
- private volatile long keepAliveTime;
-
- /**
- * If false (default), core threads stay alive even when idle.
- * If true, core threads use keepAliveTime to time out waiting
- * for work.
- */
- private volatile boolean allowCoreThreadTimeOut;
-
- /**
- * Core pool size is the minimum number of workers to keep alive
- * (and not allow to time out etc) unless allowCoreThreadTimeOut
- * is set, in which case the minimum is zero.
- */
- private volatile int corePoolSize;
-
- /**
- * Maximum pool size. Note that the actual maximum is internally
- * bounded by CAPACITY.
- */
- private volatile int maximumPoolSize;
-
- /**
- * The default rejected execution handler
- */
- private static final RejectedExecutionHandler defaultHandler =
- new AbortPolicy();
-
- /**
- * Permission required for callers of shutdown and shutdownNow.
- * We additionally require (see checkShutdownAccess) that callers
- * have permission to actually interrupt threads in the worker set
- * (as governed by Thread.interrupt, which relies on
- * ThreadGroup.checkAccess, which in turn relies on
- * SecurityManager.checkAccess). Shutdowns are attempted only if
- * these checks pass.
- *
- * All actual invocations of Thread.interrupt (see
- * interruptIdleWorkers and interruptWorkers) ignore
- * SecurityExceptions, meaning that the attempted interrupts
- * silently fail. In the case of shutdown, they should not fail
- * unless the SecurityManager has inconsistent policies, sometimes
- * allowing access to a thread and sometimes not. In such cases,
- * failure to actually interrupt threads may disable or delay full
- * termination. Other uses of interruptIdleWorkers are advisory,
- * and failure to actually interrupt will merely delay response to
- * configuration changes so is not handled exceptionally.
- */
- private static final RuntimePermission shutdownPerm =
- new RuntimePermission("modifyThread");
-
- /**
- * Class Worker mainly maintains interrupt control state for
- * threads running tasks, along with other minor bookkeeping. This
- * class opportunistically extends ReentrantLock to simplify
- * acquiring and releasing a lock surrounding each task execution.
- * This protects against interrupts that are intended to wake up a
- * worker thread waiting for a task from instead interrupting a
- * task being run.
- */
- public final class Worker extends ReentrantLock implements Runnable {
- /**
- * This class will never be serialized, but we provide a
- * serialVersionUID to suppress a javac warning.
- */
- private static final long serialVersionUID = 6138294804551838833L;
-
- /** Thread this worker is running in. Null if factory fails. */
- public final Thread thread;
- /** Initial task to run. Possibly null. */
- Runnable firstTask;
- /** Per-thread task counter */
- volatile long completedTasks;
-
- /**
- * Creates with given first task and thread from ThreadFactory.
- * @param firstTask the first task (null if none)
- */
- Worker(Runnable firstTask) {
- this.firstTask = firstTask;
- this.thread = getThreadFactory().newThread(this);
- }
-
- /** Delegates main run loop to outer runWorker */
- public void run() {
- runWorker(this);
- }
- }
-
- /*
- * Methods for setting control state
- */
-
- /**
- * Transitions runState to given target, or leaves it alone if
- * already at least the given target.
- *
- * @param targetState the desired state, either SHUTDOWN or STOP
- * (but not TIDYING or TERMINATED -- use tryTerminate for that)
- */
- private void advanceRunState(int targetState) {
- for (;;) {
- int c = ctl.get();
- if (runStateAtLeast(c, targetState) ||
- ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))
- break;
- }
- }
-
- /**
- * Transitions to TERMINATED state if either (SHUTDOWN and pool
- * and queue empty) or (STOP and pool empty). If otherwise
- * eligible to terminate but workerCount is nonzero, interrupts an
- * idle worker to ensure that shutdown signals propagate. This
- * method must be called following any action that might make
- * termination possible -- reducing worker count or removing tasks
- * from the queue during shutdown. The method is non-private to
- * allow access from ScheduledThreadPoolExecutor.
- */
- final void tryTerminate() {
- for (;;) {
- int c = ctl.get();
- if (isRunning(c) ||
- runStateAtLeast(c, TIDYING) ||
- (runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
- return;
- if (workerCountOf(c) != 0) { // Eligible to terminate
- interruptIdleWorkers(ONLY_ONE);
- return;
- }
-
- final ReentrantLock mainLock = this.mainLock;
- mainLock.lock();
- try {
- if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
- try {
- terminated();
- } finally {
- ctl.set(ctlOf(TERMINATED, 0));
- termination.signalAll();
- }
- return;
- }
- } finally {
- mainLock.unlock();
- }
- // else retry on failed CAS
- }
- }
-
- /*
- * Methods for controlling interrupts to worker threads.
- */
-
- /**
- * If there is a security manager, makes sure caller has
- * permission to shut down threads in general (see shutdownPerm).
- * If this passes, additionally makes sure the caller is allowed
- * to interrupt each worker thread. This might not be true even if
- * first check passed, if the SecurityManager treats some threads
- * specially.
- */
- private void checkShutdownAccess() {
- SecurityManager security = System.getSecurityManager();
- if (security != null) {
- security.checkPermission(shutdownPerm);
- final ReentrantLock mainLock = this.mainLock;
- mainLock.lock();
- try {
- for (Iterator itr = workers.iterator(); itr.hasNext();) {
- Worker w = (Worker)itr.next();
- security.checkAccess(w.thread);
- }
- } finally {
- mainLock.unlock();
- }
- }
- }
-
- /**
- * Interrupts all threads, even if active. Ignores SecurityExceptions
- * (in which case some threads may remain uninterrupted).
- */
- private void interruptWorkers() {
- final ReentrantLock mainLock = this.mainLock;
- mainLock.lock();
- try {
- for (Iterator itr = workers.iterator(); itr.hasNext();) {
- Worker w = (Worker)itr.next();
- try {
- w.thread.interrupt();
- } catch (SecurityException ignore) {
- }
- }
- } finally {
- mainLock.unlock();
- }
- }
-
- /**
- * Interrupts threads that might be waiting for tasks (as
- * indicated by not being locked) so they can check for
- * termination or configuration changes. Ignores
- * SecurityExceptions (in which case some threads may remain
- * uninterrupted).
- *
- * @param onlyOne If true, interrupt at most one worker. This is
- * called only from tryTerminate when termination is otherwise
- * enabled but there are still other workers. In this case, at
- * most one waiting worker is interrupted to propagate shutdown
- * signals in case all threads are currently waiting.
- * Interrupting any arbitrary thread ensures that newly arriving
- * workers since shutdown began will also eventually exit.
- * To guarantee eventual termination, it suffices to always
- * interrupt only one idle worker, but shutdown() interrupts all
- * idle workers so that redundant workers exit promptly, not
- * waiting for a straggler task to finish.
- */
- private void interruptIdleWorkers(boolean onlyOne) {
- final ReentrantLock mainLock = this.mainLock;
- mainLock.lock();
- try {
- Iterator it = workers.iterator();
- while (it.hasNext()) {
- Worker w = (Worker)it.next();
- Thread t = w.thread;
- if (!t.isInterrupted() && w.tryLock()) {
- try {
- t.interrupt();
- } catch (SecurityException ignore) {
- } finally {
- w.unlock();
- }
- }
- if (onlyOne)
- break;
- }
- } finally {
- mainLock.unlock();
- }
- }
-
- /**
- * Common form of interruptIdleWorkers, to avoid having to
- * remember what the boolean argument means.
- */
- private void interruptIdleWorkers() {
- interruptIdleWorkers(false);
- }
-
- private static final boolean ONLY_ONE = true;
-
- /**
- * Ensures that unless the pool is stopping, the current thread
- * does not have its interrupt set. This requires a double-check
- * of state in case the interrupt was cleared concurrently with a
- * shutdownNow -- if so, the interrupt is re-enabled.
- */
- private void clearInterruptsForTaskRun() {
- if (runStateLessThan(ctl.get(), STOP) &&
- Thread.interrupted() &&
- runStateAtLeast(ctl.get(), STOP))
- Thread.currentThread().interrupt();
- }
-
- /*
- * Misc utilities, most of which are also exported to
- * ScheduledThreadPoolExecutor
- */
-
- /**
- * Invokes the rejected execution handler for the given command.
- * Package-protected for use by ScheduledThreadPoolExecutor.
- */
- final void reject(Runnable command) {
- handler.rejectedExecution(command, this);
- }
-
- /**
- * Performs any further cleanup following run state transition on
- * invocation of shutdown. A no-op here, but used by
- * ScheduledThreadPoolExecutor to cancel delayed tasks.
- */
- void onShutdown() {
- }
-
- /**
- * State check needed by ScheduledThreadPoolExecutor to
- * enable running tasks during shutdown.
- *
- * @param shutdownOK true if should return true if SHUTDOWN
- */
- final boolean isRunningOrShutdown(boolean shutdownOK) {
- int rs = runStateOf(ctl.get());
- return rs == RUNNING || (rs == SHUTDOWN && shutdownOK);
- }
-
- /**
- * Drains the task queue into a new list, normally using
- * drainTo. But if the queue is a DelayQueue or any other kind of
- * queue for which poll or drainTo may fail to remove some
- * elements, it deletes them one by one.
- */
- private List drainQueue() {
- BlockingQueue q = workQueue;
- List<Runnable> taskList = new ArrayList<Runnable>();
- q.drainTo(taskList);
- if (!q.isEmpty()) {
- Runnable[] arr = (Runnable[])q.toArray(new Runnable[0]);
- for (int i=0; i<arr.length; i++) {
- Runnable r = arr[i];
- if (q.remove(r))
- taskList.add(r);
- }
- }
- return taskList;
- }
-
- /*
- * Methods for creating, running and cleaning up after workers
- */
-
- /**
- * Checks if a new worker can be added with respect to current
- * pool state and the given bound (either core or maximum). If so,
- * the worker count is adjusted accordingly, and, if possible, a
- * new worker is created and started running firstTask as its
- * first task. This method returns false if the pool is stopped or
- * eligible to shut down. It also returns false if the thread
- * factory fails to create a thread when asked, which requires a
- * backout of workerCount, and a recheck for termination, in case
- * the existence of this worker was holding up termination.
- *
- * @param firstTask the task the new thread should run first (or
- * null if none). Workers are created with an initial first task
- * (in method execute()) to bypass queuing when there are fewer
- * than corePoolSize threads (in which case we always start one),
- * or when the queue is full (in which case we must bypass queue).
- * Initially idle threads are usually created via
- * prestartCoreThread or to replace other dying workers.
- *
- * @param core if true use corePoolSize as bound, else
- * maximumPoolSize. (A boolean indicator is used here rather than a
- * value to ensure reads of fresh values after checking other pool
- * state).
- * @return true if successful
- */
- private boolean addWorker(Runnable firstTask, boolean core) {
- retry:
- for (;;) {
- int c = ctl.get();
- int rs = runStateOf(c);
-
- // Check if queue empty only if necessary.
- if (rs >= SHUTDOWN &&
- ! (rs == SHUTDOWN &&
- firstTask == null &&
- ! workQueue.isEmpty()))
- return false;
-
- for (;;) {
- int wc = workerCountOf(c);
- if (wc >= CAPACITY ||
- wc >= (core ? corePoolSize : maximumPoolSize))
- return false;
- if (compareAndIncrementWorkerCount(c))
- break retry;
- c = ctl.get(); // Re-read ctl
- if (runStateOf(c) != rs)
- continue retry;
- // else CAS failed due to workerCount change; retry inner loop
- }
- }
-
- Worker w = new Worker(firstTask);
- Thread t = w.thread;
-
- final ReentrantLock mainLock = this.mainLock;
- mainLock.lock();
- try {
- // Recheck while holding lock.
- // Back out on ThreadFactory failure or if
- // shut down before lock acquired.
- int c = ctl.get();
- int rs = runStateOf(c);
-
- if (t == null ||
- (rs >= SHUTDOWN &&
- ! (rs == SHUTDOWN &&
- firstTask == null))) {
- decrementWorkerCount();
- tryTerminate();
- return false;
- }
-
- workers.add(w);
-
- int s = workers.size();
- if (s > largestPoolSize)
- largestPoolSize = s;
- } finally {
- mainLock.unlock();
- }
-
- t.start();
- // It is possible (but unlikely) for a thread to have been
- // added to workers, but not yet started, during transition to
- // STOP, which could result in a rare missed interrupt,
- // because Thread.interrupt is not guaranteed to have any effect
- // on a non-yet-started Thread (see Thread#interrupt).
- if (runStateOf(ctl.get()) == STOP && ! t.isInterrupted())
- t.interrupt();
-
- return true;
- }
-
- /**
- * Performs cleanup and bookkeeping for a dying worker. Called
- * only from worker threads. Unless completedAbruptly is set,
- * assumes that workerCount has already been adjusted to account
- * for exit. This method removes thread from worker set, and
- * possibly terminates the pool or replaces the worker if either
- * it exited due to user task exception or if fewer than
- * corePoolSize workers are running or queue is non-empty but
- * there are no workers.
- *
- * @param w the worker
- * @param completedAbruptly if the worker died due to user exception
- */
- private void processWorkerExit(Worker w, boolean completedAbruptly) {
- if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
- decrementWorkerCount();
-
- final ReentrantLock mainLock = this.mainLock;
- mainLock.lock();
- try {
- completedTaskCount += w.completedTasks;
- workers.remove(w);
- } finally {
- mainLock.unlock();
- }
-
- tryTerminate();
-
- int c = ctl.get();
- if (runStateLessThan(c, STOP)) {
- if (!completedAbruptly) {
- int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
- if (min == 0 && ! workQueue.isEmpty())
- min = 1;
- if (workerCountOf(c) >= min)
- return; // replacement not needed
- }
- addWorker(null, false);
- }
- }
-
- /**
- * Performs blocking or timed wait for a task, depending on
- * current configuration settings, or returns null if this worker
- * must exit because of any of:
- * 1. There are more than maximumPoolSize workers (due to
- * a call to setMaximumPoolSize).
- * 2. The pool is stopped.
- * 3. The pool is shutdown and the queue is empty.
- * 4. This worker timed out waiting for a task, and timed-out
- * workers are subject to termination (that is,
- * {@code allowCoreThreadTimeOut || workerCount > corePoolSize})
- * both before and after the timed wait.
- *
- * @return task, or null if the worker must exit, in which case
- * workerCount is decremented
- */
- private Runnable getTask() {
- boolean timedOut = false; // Did the last poll() time out?
-
- retry:
- for (;;) {
- int c = ctl.get();
- int rs = runStateOf(c);
-
- // Check if queue empty only if necessary.
- if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
- decrementWorkerCount();
- return null;
- }
-
- boolean timed; // Are workers subject to culling?
-
- for (;;) {
- int wc = workerCountOf(c);
- timed = allowCoreThreadTimeOut || wc > corePoolSize;
-
- if (wc <= maximumPoolSize && ! (timedOut && timed))
- break;
- if (compareAndDecrementWorkerCount(c))
- return null;
- c = ctl.get(); // Re-read ctl
- if (runStateOf(c) != rs)
- continue retry;
- // else CAS failed due to workerCount change; retry inner loop
- }
-
- try {
- Runnable r = timed ?
- (Runnable)workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
- (Runnable)workQueue.take();
- if (r != null)
- return r;
- timedOut = true;
- } catch (InterruptedException retry) {
- timedOut = false;
- }
- }
- }
-
- /**
- * Main worker run loop. Repeatedly gets tasks from queue and
- * executes them, while coping with a number of issues:
- *
- * 1. We may start out with an initial task, in which case we
- * don't need to get the first one. Otherwise, as long as pool is
- * running, we get tasks from getTask. If it returns null then the
- * worker exits due to changed pool state or configuration
- * parameters. Other exits result from exception throws in
- * external code, in which case completedAbruptly holds, which
- * usually leads processWorkerExit to replace this thread.
- *
- * 2. Before running any task, the lock is acquired to prevent
- * other pool interrupts while the task is executing, and
- * clearInterruptsForTaskRun called to ensure that unless pool is
- * stopping, this thread does not have its interrupt set.
- *
- * 3. Each task run is preceded by a call to beforeExecute, which
- * might throw an exception, in which case we cause thread to die
- * (breaking loop with completedAbruptly true) without processing
- * the task.
- *
- * 4. Assuming beforeExecute completes normally, we run the task,
- * gathering any of its thrown exceptions to send to
- * afterExecute. We separately handle RuntimeException, Error
- * (both of which the specs guarantee that we trap) and arbitrary
- * Throwables. Because we cannot rethrow Throwables within
- * Runnable.run, we wrap them within Errors on the way out (to the
- * thread's UncaughtExceptionHandler). Any thrown exception also
- * conservatively causes thread to die.
- *
- * 5. After task.run completes, we call afterExecute, which may
- * also throw an exception, which will also cause thread to
- * die. According to JLS Sec 14.20, this exception is the one that
- * will be in effect even if task.run throws.
- *
- * The net effect of the exception mechanics is that afterExecute
- * and the thread's UncaughtExceptionHandler have as accurate
- * information as we can provide about any problems encountered by
- * user code.
- *
- * @param w the worker
- */
- final void runWorker(Worker w) {
- Runnable task = w.firstTask;
- w.firstTask = null;
- boolean completedAbruptly = true;
- try {
- while (task != null || (task = getTask()) != null) {
- w.lock();
- clearInterruptsForTaskRun();
- try {
- beforeExecute(w.thread, task);
- Throwable thrown = null;
- try {
- task.run();
- } catch (RuntimeException x) {
- thrown = x; throw x;
- } catch (Error x) {
- thrown = x; throw x;
- } catch (Throwable x) {
- thrown = x; throw new Error(x);
- } finally {
- afterExecute(task, thrown);
- }
- } finally {
- task = null;
- w.completedTasks++;
- w.unlock();
- }
- }
- completedAbruptly = false;
- } finally {
- processWorkerExit(w, completedAbruptly);
- }
- }
-
- // Public constructors and methods
-
- /**
- * Creates a new {@code ThreadPoolExecutor} with the given initial
- * parameters and default thread factory and rejected execution handler.
- * It may be more convenient to use one of the {@link Executors} factory
- * methods instead of this general purpose constructor.
- *
- * @param corePoolSize the number of threads to keep in the pool, even
- * if they are idle, unless {@code allowCoreThreadTimeOut} is set
- * @param maximumPoolSize the maximum number of threads to allow in the
- * pool
- * @param keepAliveTime when the number of threads is greater than
- * the core, this is the maximum time that excess idle threads
- * will wait for new tasks before terminating.
- * @param unit the time unit for the {@code keepAliveTime} argument
- * @param workQueue the queue to use for holding tasks before they are
- * executed. This queue will hold only the {@code Runnable}
- * tasks submitted by the {@code execute} method.
- * @throws IllegalArgumentException if one of the following holds:<br>
- * {@code corePoolSize < 0}<br>
- * {@code keepAliveTime < 0}<br>
- * {@code maximumPoolSize <= 0}<br>
- * {@code maximumPoolSize < corePoolSize}
- * @throws NullPointerException if {@code workQueue} is null
- */
- public ThreadPoolExecutor(int corePoolSize,
- int maximumPoolSize,
- long keepAliveTime,
- TimeUnit unit,
- BlockingQueue workQueue) {
- this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
- Executors.defaultThreadFactory(), defaultHandler);
- }
-
- /**
- * Creates a new {@code ThreadPoolExecutor} with the given initial
- * parameters and default rejected execution handler.
- *
- * @param corePoolSize the number of threads to keep in the pool, even
- * if they are idle, unless {@code allowCoreThreadTimeOut} is set
- * @param maximumPoolSize the maximum number of threads to allow in the
- * pool
- * @param keepAliveTime when the number of threads is greater than
- * the core, this is the maximum time that excess idle threads
- * will wait for new tasks before terminating.
- * @param unit the time unit for the {@code keepAliveTime} argument
- * @param workQueue the queue to use for holding tasks before they are
- * executed. This queue will hold only the {@code Runnable}
- * tasks submitted by the {@code execute} method.
- * @param threadFactory the factory to use when the executor
- * creates a new thread
- * @throws IllegalArgumentException if one of the following holds:<br>
- * {@code corePoolSize < 0}<br>
- * {@code keepAliveTime < 0}<br>
- * {@code maximumPoolSize <= 0}<br>
- * {@code maximumPoolSize < corePoolSize}
- * @throws NullPointerException if {@code workQueue}
- * or {@code threadFactory} is null
- */
- public ThreadPoolExecutor(int corePoolSize,
- int maximumPoolSize,
- long keepAliveTime,
- TimeUnit unit,
- BlockingQueue workQueue,
- ThreadFactory threadFactory) {
- this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
- threadFactory, defaultHandler);
- }
-
- /**
- * Creates a new {@code ThreadPoolExecutor} with the given initial
- * parameters and default thread factory.
- *
- * @param corePoolSize the number of threads to keep in the pool, even
- * if they are idle, unless {@code allowCoreThreadTimeOut} is set
- * @param maximumPoolSize the maximum number of threads to allow in the
- * pool
- * @param keepAliveTime when the number of threads is greater than
- * the core, this is the maximum time that excess idle threads
- * will wait for new tasks before terminating.
- * @param unit the time unit for the {@code keepAliveTime} argument
- * @param workQueue the queue to use for holding tasks before they are
- * executed. This queue will hold only the {@code Runnable}
- * tasks submitted by the {@code execute} method.
- * @param handler the handler to use when execution is blocked
- * because the thread bounds and queue capacities are reached
- * @throws IllegalArgumentException if one of the following holds:<br>
- * {@code corePoolSize < 0}<br>
- * {@code keepAliveTime < 0}<br>
- * {@code maximumPoolSize <= 0}<br>
- * {@code maximumPoolSize < corePoolSize}
- * @throws NullPointerException if {@code workQueue}
- * or {@code handler} is null
- */
- public ThreadPoolExecutor(int corePoolSize,
- int maximumPoolSize,
- long keepAliveTime,
- TimeUnit unit,
- BlockingQueue workQueue,
- RejectedExecutionHandler handler) {
- this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
- Executors.defaultThreadFactory(), handler);
- }
-
- /**
- * Creates a new {@code ThreadPoolExecutor} with the given initial
- * parameters.
- *
- * @param corePoolSize the number of threads to keep in the pool, even
- * if they are idle, unless {@code allowCoreThreadTimeOut} is set
- * @param maximumPoolSize the maximum number of threads to allow in the
- * pool
- * @param keepAliveTime when the number of threads is greater than
- * the core, this is the maximum time that excess idle threads
- * will wait for new tasks before terminating.
- * @param unit the time unit for the {@code keepAliveTime} argument
- * @param workQueue the queue to use for holding tasks before they are
- * executed. This queue will hold only the {@code Runnable}
- * tasks submitted by the {@code execute} method.
- * @param threadFactory the factory to use when the executor
- * creates a new thread
- * @param handler the handler to use when execution is blocked
- * because the thread bounds and queue capacities are reached
- * @throws IllegalArgumentException if one of the following holds:<br>
- * {@code corePoolSize < 0}<br>
- * {@code keepAliveTime < 0}<br>
- * {@code maximumPoolSize <= 0}<br>
- * {@code maximumPoolSize < corePoolSize}
- * @throws NullPointerException if {@code workQueue}
- * or {@code threadFactory} or {@code handler} is null
- */
- public ThreadPoolExecutor(int corePoolSize,
- int maximumPoolSize,
- long keepAliveTime,
- TimeUnit unit,
- BlockingQueue workQueue,
- ThreadFactory threadFactory,
- RejectedExecutionHandler handler) {
- if (corePoolSize < 0 ||
- maximumPoolSize <= 0 ||
- maximumPoolSize < corePoolSize ||
- keepAliveTime < 0)
- throw new IllegalArgumentException();
- if (workQueue == null || threadFactory == null || handler == null)
- throw new NullPointerException();
- this.corePoolSize = corePoolSize;
- this.maximumPoolSize = maximumPoolSize;
- this.workQueue = workQueue;
- this.keepAliveTime = unit.toNanos(keepAliveTime);
- this.threadFactory = threadFactory;
- this.handler = handler;
- }
-
- /**
- * Executes the given task sometime in the future. The task
- * may execute in a new thread or in an existing pooled thread.
- *
- * If the task cannot be submitted for execution, either because this
- * executor has been shutdown or because its capacity has been reached,
- * the task is handled by the current {@code RejectedExecutionHandler}.
- *
- * @param command the task to execute
- * @throws RejectedExecutionException at discretion of
- * {@code RejectedExecutionHandler}, if the task
- * cannot be accepted for execution
- * @throws NullPointerException if {@code command} is null
- */
- public void execute(Runnable command) {
- if (command == null)
- throw new NullPointerException();
- /*
- * Proceed in 3 steps:
- *
- * 1. If fewer than corePoolSize threads are running, try to
- * start a new thread with the given command as its first
- * task. The call to addWorker atomically checks runState and
- * workerCount, and so prevents false alarms that would add
- * threads when it shouldn't, by returning false.
- *
- * 2. If a task can be successfully queued, then we still need
- * to double-check whether we should have added a thread
- * (because existing ones died since last checking) or that
- * the pool shut down since entry into this method. So we
- * recheck state and if necessary roll back the enqueuing if
- * stopped, or start a new thread if there are none.
- *
- * 3. If we cannot queue task, then we try to add a new
- * thread. If it fails, we know we are shut down or saturated
- * and so reject the task.
- */
- int c = ctl.get();
- if (workerCountOf(c) < corePoolSize) {
- if (addWorker(command, true))
- return;
- c = ctl.get();
- }
- if (isRunning(c) && workQueue.offer(command)) {
- int recheck = ctl.get();
- if (! isRunning(recheck) && remove(command))
- reject(command);
- else if (workerCountOf(recheck) == 0)
- addWorker(null, false);
- }
- else if (!addWorker(command, false))
- reject(command);
- }
-
- /**
- * Initiates an orderly shutdown in which previously submitted
- * tasks are executed, but no new tasks will be accepted.
- * Invocation has no additional effect if already shut down.
- *
- * @throws SecurityException {@inheritDoc}
- */
- public void shutdown() {
- final ReentrantLock mainLock = this.mainLock;
- mainLock.lock();
- try {
- checkShutdownAccess();
- advanceRunState(SHUTDOWN);
- interruptIdleWorkers();
- onShutdown(); // hook for ScheduledThreadPoolExecutor
- } finally {
- mainLock.unlock();
- }
- tryTerminate();
- }
-
- /**
- * Attempts to stop all actively executing tasks, halts the
- * processing of waiting tasks, and returns a list of the tasks
- * that were awaiting execution. These tasks are drained (removed)
- * from the task queue upon return from this method.
- *
- * <p>There are no guarantees beyond best-effort attempts to stop
- * processing actively executing tasks. This implementation
- * cancels tasks via {@link Thread#interrupt}, so any task that
- * fails to respond to interrupts may never terminate.
- *
- * @throws SecurityException {@inheritDoc}
- */
- public List shutdownNow() {
- List tasks;
- final ReentrantLock mainLock = this.mainLock;
- mainLock.lock();
- try {
- checkShutdownAccess();
- advanceRunState(STOP);
- interruptWorkers();
- tasks = drainQueue();
- } finally {
- mainLock.unlock();
- }
- tryTerminate();
- return tasks;
- }
-
- public boolean isShutdown() {
- return ! isRunning(ctl.get());
- }
-
- /**
- * Returns true if this executor is in the process of terminating
- * after {@link #shutdown} or {@link #shutdownNow} but has not
- * completely terminated. This method may be useful for
- * debugging. A return of {@code true} reported a sufficient
- * period after shutdown may indicate that submitted tasks have
- * ignored or suppressed interruption, causing this executor not
- * to properly terminate.
- *
- * @return true if terminating but not yet terminated
- */
- public boolean isTerminating() {
- int c = ctl.get();
- return ! isRunning(c) && runStateLessThan(c, TERMINATED);
- }
-
- public boolean isTerminated() {
- return runStateAtLeast(ctl.get(), TERMINATED);
- }
-
- public boolean awaitTermination(long timeout, TimeUnit unit)
- throws InterruptedException {
- long nanos = unit.toNanos(timeout);
- long deadline = Utils.nanoTime() + nanos;
- final ReentrantLock mainLock = this.mainLock;
- mainLock.lock();
- try {
- if (runStateAtLeast(ctl.get(), TERMINATED))
- return true;
- while (nanos > 0) {
- termination.await(nanos, TimeUnit.NANOSECONDS);
- if (runStateAtLeast(ctl.get(), TERMINATED))
- return true;
- nanos = deadline - Utils.nanoTime();
- }
- return false;
- } finally {
- mainLock.unlock();
- }
- }
-
- /**
- * Invokes {@code shutdown} when this executor is no longer
- * referenced and it has no threads.
- */
- protected void finalize() {
- shutdown();
- }
-
- /**
- * Sets the thread factory used to create new threads.
- *
- * @param threadFactory the new thread factory
- * @throws NullPointerException if threadFactory is null
- * @see #getThreadFactory
- */
- public void setThreadFactory(ThreadFactory threadFactory) {
- if (threadFactory == null)
- throw new NullPointerException();
- this.threadFactory = threadFactory;
- }
-
- /**
- * Returns the thread factory used to create new threads.
- *
- * @return the current thread factory
- * @see #setThreadFactory
- */
- public ThreadFactory getThreadFactory() {
- return threadFactory;
- }
-
- /**
- * Sets a new handler for unexecutable tasks.
- *
- * @param handler the new handler
- * @throws NullPointerException if handler is null
- * @see #getRejectedExecutionHandler
- */
- public void setRejectedExecutionHandler(RejectedExecutionHandler handler) {
- if (handler == null)
- throw new NullPointerException();
- this.handler = handler;
- }
-
- /**
- * Returns the current handler for unexecutable tasks.
- *
- * @return the current handler
- * @see #setRejectedExecutionHandler
- */
- public RejectedExecutionHandler getRejectedExecutionHandler() {
- return handler;
- }
-
- /**
- * Sets the core number of threads. This overrides any value set
- * in the constructor. If the new value is smaller than the
- * current value, excess existing threads will be terminated when
- * they next become idle. If larger, new threads will, if needed,
- * be started to execute any queued tasks.
- *
- * @param corePoolSize the new core size
- * @throws IllegalArgumentException if {@code corePoolSize < 0}
- * @see #getCorePoolSize
- */
- public void setCorePoolSize(int corePoolSize) {
- if (corePoolSize < 0)
- throw new IllegalArgumentException();
- int delta = corePoolSize - this.corePoolSize;
- this.corePoolSize = corePoolSize;
- if (workerCountOf(ctl.get()) > corePoolSize)
- interruptIdleWorkers();
- else if (delta > 0) {
- // We don't really know how many new threads are "needed".
- // As a heuristic, prestart enough new workers (up to new
- // core size) to handle the current number of tasks in
- // queue, but stop if queue becomes empty while doing so.
- int k = Math.min(delta, workQueue.size());
- while (k-- > 0 && addWorker(null, true)) {
- if (workQueue.isEmpty())
- break;
- }
- }
- }
-
- /**
- * Returns the core number of threads.
- *
- * @return the core number of threads
- * @see #setCorePoolSize
- */
- public int getCorePoolSize() {
- return corePoolSize;
- }
-
- /**
- * Starts a core thread, causing it to idly wait for work. This
- * overrides the default policy of starting core threads only when
- * new tasks are executed. This method will return {@code false}
- * if all core threads have already been started.
- *
- * @return {@code true} if a thread was started
- */
- public boolean prestartCoreThread() {
- return workerCountOf(ctl.get()) < corePoolSize &&
- addWorker(null, true);
- }
-
- /**
- * Starts all core threads, causing them to idly wait for work. This
- * overrides the default policy of starting core threads only when
- * new tasks are executed.
- *
- * @return the number of threads started
- */
- public int prestartAllCoreThreads() {
- int n = 0;
- while (addWorker(null, true))
- ++n;
- return n;
- }
-
- /**
- * Returns true if this pool allows core threads to time out and
- * terminate if no tasks arrive within the keepAlive time, being
- * replaced if needed when new tasks arrive. When true, the same
- * keep-alive policy applying to non-core threads applies also to
- * core threads. When false (the default), core threads are never
- * terminated due to lack of incoming tasks.
- *
- * @return {@code true} if core threads are allowed to time out,
- * else {@code false}
- *
- * @since 1.6
- */
- public boolean allowsCoreThreadTimeOut() {
- return allowCoreThreadTimeOut;
- }
-
- /**
- * Sets the policy governing whether core threads may time out and
- * terminate if no tasks arrive within the keep-alive time, being
- * replaced if needed when new tasks arrive. When false, core
- * threads are never terminated due to lack of incoming
- * tasks. When true, the same keep-alive policy applying to
- * non-core threads applies also to core threads. To avoid
- * continual thread replacement, the keep-alive time must be
- * greater than zero when setting {@code true}. This method
- * should in general be called before the pool is actively used.
- *
- * @param value {@code true} if should time out, else {@code false}
- * @throws IllegalArgumentException if value is {@code true}
- * and the current keep-alive time is not greater than zero
- *
- * @since 1.6
- */
- public void allowCoreThreadTimeOut(boolean value) {
- if (value && keepAliveTime <= 0)
- throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
- if (value != allowCoreThreadTimeOut) {
- allowCoreThreadTimeOut = value;
- if (value)
- interruptIdleWorkers();
- }
- }
-
- /**
- * Sets the maximum allowed number of threads. This overrides any
- * value set in the constructor. If the new value is smaller than
- * the current value, excess existing threads will be
- * terminated when they next become idle.
- *
- * @param maximumPoolSize the new maximum
- * @throws IllegalArgumentException if the new maximum is
- * less than or equal to zero, or
- * less than the {@linkplain #getCorePoolSize core pool size}
- * @see #getMaximumPoolSize
- */
- public void setMaximumPoolSize(int maximumPoolSize) {
- if (maximumPoolSize <= 0 || maximumPoolSize < corePoolSize)
- throw new IllegalArgumentException();
- this.maximumPoolSize = maximumPoolSize;
- if (workerCountOf(ctl.get()) > maximumPoolSize)
- interruptIdleWorkers();
- }
-
- /**
- * Returns the maximum allowed number of threads.
- *
- * @return the maximum allowed number of threads
- * @see #setMaximumPoolSize
- */
- public int getMaximumPoolSize() {
- return maximumPoolSize;
- }
-
- /**
- * Sets the time limit for which threads may remain idle before
- * being terminated. If there are more than the core number of
- * threads currently in the pool, after waiting this amount of
- * time without processing a task, excess threads will be
- * terminated. This overrides any value set in the constructor.
- *
- * @param time the time to wait. A time value of zero will cause
- * excess threads to terminate immediately after executing tasks.
- * @param unit the time unit of the {@code time} argument
- * @throws IllegalArgumentException if {@code time} less than zero or
- * if {@code time} is zero and {@code allowsCoreThreadTimeOut}
- * @see #getKeepAliveTime
- */
- public void setKeepAliveTime(long time, TimeUnit unit) {
- if (time < 0)
- throw new IllegalArgumentException();
- if (time == 0 && allowsCoreThreadTimeOut())
- throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
- long keepAliveTime = unit.toNanos(time);
- long delta = keepAliveTime - this.keepAliveTime;
- this.keepAliveTime = keepAliveTime;
- if (delta < 0)
- interruptIdleWorkers();
- }
-
- /**
- * Returns the thread keep-alive time, which is the amount of time
- * that threads in excess of the core pool size may remain
- * idle before being terminated.
- *
- * @param unit the desired time unit of the result
- * @return the time limit
- * @see #setKeepAliveTime
- */
- public long getKeepAliveTime(TimeUnit unit) {
- return unit.convert(keepAliveTime, TimeUnit.NANOSECONDS);
- }
-
- /* User-level queue utilities */
-
- /**
- * Returns the task queue used by this executor. Access to the
- * task queue is intended primarily for debugging and monitoring.
- * This queue may be in active use. Retrieving the task queue
- * does not prevent queued tasks from executing.
- *
- * @return the task queue
- */
- public BlockingQueue getQueue() {
- return workQueue;
- }
-
- /**
- * Removes this task from the executor's internal queue if it is
- * present, thus causing it not to be run if it has not already
- * started.
- *
- * <p> This method may be useful as one part of a cancellation
- * scheme. It may fail to remove tasks that have been converted
- * into other forms before being placed on the internal queue. For
- * example, a task entered using {@code submit} might be
- * converted into a form that maintains {@code Future} status.
- * However, in such cases, method {@link #purge} may be used to
- * remove those Futures that have been cancelled.
- *
- * @param task the task to remove
- * @return true if the task was removed
- */
- public boolean remove(Runnable task) {
- boolean removed = workQueue.remove(task);
- tryTerminate(); // In case SHUTDOWN and now empty
- return removed;
- }
-
- /**
- * Tries to remove from the work queue all {@link Future}
- * tasks that have been cancelled. This method can be useful as a
- * storage reclamation operation, that has no other impact on
- * functionality. Cancelled tasks are never executed, but may
- * accumulate in work queues until worker threads can actively
- * remove them. Invoking this method instead tries to remove them now.
- * However, this method may fail to remove tasks in
- * the presence of interference by other threads.
- */
- public void purge() {
- final BlockingQueue q = workQueue;
- try {
- Iterator it = q.iterator();
- while (it.hasNext()) {
- Runnable r = (Runnable)it.next();
- if (r instanceof Future && ((Future)r).isCancelled())
- it.remove();
- }
- } catch (ConcurrentModificationException fallThrough) {
- // Take slow path if we encounter interference during traversal.
- // Make copy for traversal and call remove for cancelled entries.
- // The slow path is more likely to be O(N*N).
- Object[] arr = q.toArray();
- for (int i=0; i<arr.length; i++) {
- Object r = arr[i];
- if (r instanceof Future && ((Future)r).isCancelled())
- q.remove(r);
- }
- }
-
- tryTerminate(); // In case SHUTDOWN and now empty
- }
-
- /* Statistics */
-
- /**
- * Returns the current number of threads in the pool.
- *
- * @return the number of threads
- */
- public int getPoolSize() {
- final ReentrantLock mainLock = this.mainLock;
- mainLock.lock();
- try {
- // Remove rare and surprising possibility of
- // isTerminated() && getPoolSize() > 0
- return runStateAtLeast(ctl.get(), TIDYING) ? 0
- : workers.size();
- } finally {
- mainLock.unlock();
- }
- }
-
- /**
- * Returns the approximate number of threads that are actively
- * executing tasks.
- *
- * @return the number of threads
- */
- public int getActiveCount() {
- final ReentrantLock mainLock = this.mainLock;
- mainLock.lock();
- try {
- int n = 0;
- for (Iterator itr = workers.iterator(); itr.hasNext();) {
- Worker w = (Worker)itr.next();
- if (w.isLocked())
- ++n;
- }
- return n;
- } finally {
- mainLock.unlock();
- }
- }
-
- /**
- * Returns the largest number of threads that have ever
- * simultaneously been in the pool.
- *
- * @return the number of threads
- */
- public int getLargestPoolSize() {
- final ReentrantLock mainLock = this.mainLock;
- mainLock.lock();
- try {
- return largestPoolSize;
- } finally {
- mainLock.unlock();
- }
- }
-
- /**
- * Returns the approximate total number of tasks that have ever been
- * scheduled for execution. Because the states of tasks and
- * threads may change dynamically during computation, the returned
- * value is only an approximation.
- *
- * @return the number of tasks
- */
- public long getTaskCount() {
- final ReentrantLock mainLock = this.mainLock;
- mainLock.lock();
- try {
- long n = completedTaskCount;
- for (Iterator itr = workers.iterator(); itr.hasNext();) {
- Worker w = (Worker)itr.next();
- n += w.completedTasks;
- if (w.isLocked())
- ++n;
- }
- return n + workQueue.size();
- } finally {
- mainLock.unlock();
- }
- }
-
- /**
- * Returns the approximate total number of tasks that have
- * completed execution. Because the states of tasks and threads
- * may change dynamically during computation, the returned value
- * is only an approximation, but one that does not ever decrease
- * across successive calls.
- *
- * @return the number of tasks
- */
- public long getCompletedTaskCount() {
- final ReentrantLock mainLock = this.mainLock;
- mainLock.lock();
- try {
- long n = completedTaskCount;
- for (Iterator itr = workers.iterator(); itr.hasNext();) {
- Worker w = (Worker)itr.next();
- n += w.completedTasks;
- }
- return n;
- } finally {
- mainLock.unlock();
- }
- }
-
- /* Extension hooks */
-
- /**
- * Method invoked prior to executing the given Runnable in the
- * given thread. This method is invoked by thread {@code t} that
- * will execute task {@code r}, and may be used to re-initialize
- * ThreadLocals, or to perform logging.
- *
- * <p>This implementation does nothing, but may be customized in
- * subclasses. Note: To properly nest multiple overridings, subclasses
- * should generally invoke {@code super.beforeExecute} at the end of
- * this method.
- *
- * @param t the thread that will run task {@code r}
- * @param r the task that will be executed
- */
- protected void beforeExecute(Thread t, Runnable r) { }
-
- /**
- * Method invoked upon completion of execution of the given Runnable.
- * This method is invoked by the thread that executed the task. If
- * non-null, the Throwable is the uncaught {@code RuntimeException}
- * or {@code Error} that caused execution to terminate abruptly.
- *
- * <p>This implementation does nothing, but may be customized in
- * subclasses. Note: To properly nest multiple overridings, subclasses
- * should generally invoke {@code super.afterExecute} at the
- * beginning of this method.
- *
- * <p><b>Note:</b> When actions are enclosed in tasks (such as
- * {@link FutureTask}) either explicitly or via methods such as
- * {@code submit}, these task objects catch and maintain
- * computational exceptions, and so they do not cause abrupt
- * termination, and the internal exceptions are <em>not</em>
- * passed to this method. If you would like to trap both kinds of
- * failures in this method, you can further probe for such cases,
- * as in this sample subclass that prints either the direct cause
- * or the underlying exception if a task has been aborted:
- *
- * <pre> {@code
- * class ExtendedExecutor extends ThreadPoolExecutor {
- * // ...
- * protected void afterExecute(Runnable r, Throwable t) {
- * super.afterExecute(r, t);
- * if (t == null && r instanceof Future<?>) {
- * try {
- * Object result = ((Future<?>) r).get();
- * } catch (CancellationException ce) {
- * t = ce;
- * } catch (ExecutionException ee) {
- * t = ee.getCause();
- * } catch (InterruptedException ie) {
- * Thread.currentThread().interrupt(); // ignore/reset
- * }
- * }
- * if (t != null)
- * System.out.println(t);
- * }
- * }}</pre>
- *
- * @param r the runnable that has completed
- * @param t the exception that caused termination, or null if
- * execution completed normally
- */
- protected void afterExecute(Runnable r, Throwable t) { }
-
- /**
- * Method invoked when the Executor has terminated. Default
- * implementation does nothing. Note: To properly nest multiple
- * overridings, subclasses should generally invoke
- * {@code super.terminated} within this method.
- */
- protected void terminated() { }
-
- /* Predefined RejectedExecutionHandlers */
-
- /**
- * A handler for rejected tasks that runs the rejected task
- * directly in the calling thread of the {@code execute} method,
- * unless the executor has been shut down, in which case the task
- * is discarded.
- */
- public static class CallerRunsPolicy implements RejectedExecutionHandler {
- /**
- * Creates a {@code CallerRunsPolicy}.
- */
- public CallerRunsPolicy() { }
-
- /**
- * Executes task r in the caller's thread, unless the executor
- * has been shut down, in which case the task is discarded.
- *
- * @param r the runnable task requested to be executed
- * @param e the executor attempting to execute this task
- */
- public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
- if (!e.isShutdown()) {
- r.run();
- }
- }
- }
-
- /**
- * A handler for rejected tasks that throws a
- * {@code RejectedExecutionException}.
- */
- public static class AbortPolicy implements RejectedExecutionHandler {
- /**
- * Creates an {@code AbortPolicy}.
- */
- public AbortPolicy() { }
-
- /**
- * Always throws RejectedExecutionException.
- *
- * @param r the runnable task requested to be executed
- * @param e the executor attempting to execute this task
- * @throws RejectedExecutionException always.
- */
- public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
- throw new RejectedExecutionException();
- }
- }
-
- /**
- * A handler for rejected tasks that silently discards the
- * rejected task.
- */
- public static class DiscardPolicy implements RejectedExecutionHandler {
- /**
- * Creates a {@code DiscardPolicy}.
- */
- public DiscardPolicy() { }
-
- /**
- * Does nothing, which has the effect of discarding task r.
- *
- * @param r the runnable task requested to be executed
- * @param e the executor attempting to execute this task
- */
- public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
- }
- }
-
- /**
- * A handler for rejected tasks that discards the oldest unhandled
- * request and then retries {@code execute}, unless the executor
- * is shut down, in which case the task is discarded.
- */
- public static class DiscardOldestPolicy implements RejectedExecutionHandler {
- /**
- * Creates a {@code DiscardOldestPolicy} for the given executor.
- */
- public DiscardOldestPolicy() { }
-
- /**
- * Obtains and ignores the next task that the executor
- * would otherwise execute, if one is immediately available,
- * and then retries execution of task r, unless the executor
- * is shut down, in which case task r is instead discarded.
- *
- * @param r the runnable task requested to be executed
- * @param e the executor attempting to execute this task
- */
- public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
- if (!e.isShutdown()) {
- e.getQueue().poll();
- e.execute(r);
- }
- }
- }
-}
diff --git a/src/actors/scala/actors/threadpool/TimeUnit.java b/src/actors/scala/actors/threadpool/TimeUnit.java
deleted file mode 100644
index c443750e33..0000000000
--- a/src/actors/scala/actors/threadpool/TimeUnit.java
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
- */
-
-package scala.actors.threadpool;
-
-import java.io.InvalidObjectException;
-import java.io.ObjectStreamException;
-
-/**
- * A <tt>TimeUnit</tt> represents time durations at a given unit of
- * granularity and provides utility methods to convert across units,
- * and to perform timing and delay operations in these units. A
- * <tt>TimeUnit</tt> does not maintain time information, but only
- * helps organize and use time representations that may be maintained
- * separately across various contexts. A nanosecond is defined as one
- * thousandth of a microsecond, a microsecond as one thousandth of a
- * millisecond, a millisecond as one thousandth of a second, a minute
- * as sixty seconds, an hour as sixty minutes, and a day as twenty four
- * hours.
- *
- * <p>A <tt>TimeUnit</tt> is mainly used to inform time-based methods
- * how a given timing parameter should be interpreted. For example,
- * the following code will timeout in 50 milliseconds if the {@link
- * edu.emory.mathcs.backport.java.util.concurrent.locks.Lock lock} is not available:
- *
- * <pre> Lock lock = ...;
- * if ( lock.tryLock(50L, TimeUnit.MILLISECONDS) ) ...
- * </pre>
- * while this code will timeout in 50 seconds:
- * <pre>
- * Lock lock = ...;
- * if ( lock.tryLock(50L, TimeUnit.SECONDS) ) ...
- * </pre>
- *
- * Note however, that there is no guarantee that a particular timeout
- * implementation will be able to notice the passage of time at the
- * same granularity as the given <tt>TimeUnit</tt>.
- *
- * @since 1.5
- * @author Doug Lea
- */
-public abstract class TimeUnit implements java.io.Serializable {
-
- public static final TimeUnit NANOSECONDS = new TimeUnit(0, "NANOSECONDS") {
- private final static long serialVersionUID = 535148490883208361L;
- public long toNanos(long d) { return d; }
- public long toMicros(long d) { return d/(C1/C0); }
- public long toMillis(long d) { return d/(C2/C0); }
- public long toSeconds(long d) { return d/(C3/C0); }
- public long toMinutes(long d) { return d/(C4/C0); }
- public long toHours(long d) { return d/(C5/C0); }
- public long toDays(long d) { return d/(C6/C0); }
- public long convert(long d, TimeUnit u) { return u.toNanos(d); }
- int excessNanos(long d, long m) { return (int)(d - (m*C2)); }
- };
- public static final TimeUnit MICROSECONDS = new TimeUnit(1, "MICROSECONDS") {
- private final static long serialVersionUID = 2185906575929579108L;
- public long toNanos(long d) { return x(d, C1/C0, MAX/(C1/C0)); }
- public long toMicros(long d) { return d; }
- public long toMillis(long d) { return d/(C2/C1); }
- public long toSeconds(long d) { return d/(C3/C1); }
- public long toMinutes(long d) { return d/(C4/C1); }
- public long toHours(long d) { return d/(C5/C1); }
- public long toDays(long d) { return d/(C6/C1); }
- public long convert(long d, TimeUnit u) { return u.toMicros(d); }
- int excessNanos(long d, long m) { return (int)((d*C1) - (m*C2)); }
- };
- public static final TimeUnit MILLISECONDS = new TimeUnit(2, "MILLISECONDS") {
- private final static long serialVersionUID = 9032047794123325184L;
- public long toNanos(long d) { return x(d, C2/C0, MAX/(C2/C0)); }
- public long toMicros(long d) { return x(d, C2/C1, MAX/(C2/C1)); }
- public long toMillis(long d) { return d; }
- public long toSeconds(long d) { return d/(C3/C2); }
- public long toMinutes(long d) { return d/(C4/C2); }
- public long toHours(long d) { return d/(C5/C2); }
- public long toDays(long d) { return d/(C6/C2); }
- public long convert(long d, TimeUnit u) { return u.toMillis(d); }
- int excessNanos(long d, long m) { return 0; }
- };
- public static final TimeUnit SECONDS = new TimeUnit(3, "SECONDS") {
- private final static long serialVersionUID = 227755028449378390L;
- public long toNanos(long d) { return x(d, C3/C0, MAX/(C3/C0)); }
- public long toMicros(long d) { return x(d, C3/C1, MAX/(C3/C1)); }
- public long toMillis(long d) { return x(d, C3/C2, MAX/(C3/C2)); }
- public long toSeconds(long d) { return d; }
- public long toMinutes(long d) { return d/(C4/C3); }
- public long toHours(long d) { return d/(C5/C3); }
- public long toDays(long d) { return d/(C6/C3); }
- public long convert(long d, TimeUnit u) { return u.toSeconds(d); }
- int excessNanos(long d, long m) { return 0; }
- };
- public static final TimeUnit MINUTES = new TimeUnit(4, "MINUTES") {
- private final static long serialVersionUID = 1827351566402609187L;
- public long toNanos(long d) { return x(d, C4/C0, MAX/(C4/C0)); }
- public long toMicros(long d) { return x(d, C4/C1, MAX/(C4/C1)); }
- public long toMillis(long d) { return x(d, C4/C2, MAX/(C4/C2)); }
- public long toSeconds(long d) { return x(d, C4/C3, MAX/(C4/C3)); }
- public long toMinutes(long d) { return d; }
- public long toHours(long d) { return d/(C5/C4); }
- public long toDays(long d) { return d/(C6/C4); }
- public long convert(long d, TimeUnit u) { return u.toMinutes(d); }
- int excessNanos(long d, long m) { return 0; }
- };
- public static final TimeUnit HOURS = new TimeUnit(5, "HOURS") {
- private final static long serialVersionUID = -6438436134732089810L;
- public long toNanos(long d) { return x(d, C5/C0, MAX/(C5/C0)); }
- public long toMicros(long d) { return x(d, C5/C1, MAX/(C5/C1)); }
- public long toMillis(long d) { return x(d, C5/C2, MAX/(C5/C2)); }
- public long toSeconds(long d) { return x(d, C5/C3, MAX/(C5/C3)); }
- public long toMinutes(long d) { return x(d, C5/C4, MAX/(C5/C4)); }
- public long toHours(long d) { return d; }
- public long toDays(long d) { return d/(C6/C5); }
- public long convert(long d, TimeUnit u) { return u.toHours(d); }
- int excessNanos(long d, long m) { return 0; }
- };
- public static final TimeUnit DAYS = new TimeUnit(6, "DAYS") {
- private final static long serialVersionUID = 567463171959674600L;
- public long toNanos(long d) { return x(d, C6/C0, MAX/(C6/C0)); }
- public long toMicros(long d) { return x(d, C6/C1, MAX/(C6/C1)); }
- public long toMillis(long d) { return x(d, C6/C2, MAX/(C6/C2)); }
- public long toSeconds(long d) { return x(d, C6/C3, MAX/(C6/C3)); }
- public long toMinutes(long d) { return x(d, C6/C4, MAX/(C6/C4)); }
- public long toHours(long d) { return x(d, C6/C5, MAX/(C6/C5)); }
- public long toDays(long d) { return d; }
- public long convert(long d, TimeUnit u) { return u.toDays(d); }
- int excessNanos(long d, long m) { return 0; }
- };
-
- private static final TimeUnit[] values = new TimeUnit[]
- { NANOSECONDS, MICROSECONDS, MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS };
-
- public static TimeUnit[] values() {
- return (TimeUnit[])values.clone();
- }
-
- /**
- * Returns the enum constant of this type with the specified name. The
- * string must match <em>exactly</em> an identifier used to declare an
- * enum constant in this type. (Extraneous whitespace characters are not
- * permitted.)
- *
- * @param name the name of the enum constant to be returned
- * @return the enum constant with the specified name
- * @throws IllegalArgumentException
- * if this enum type has no constant with the specified name
- */
- public static TimeUnit valueOf(String name) {
- for (int i = 0; i < values.length; i++) {
- if (values[i].name.equals(name)) {
- return values[i];
- }
- }
- throw new IllegalArgumentException("No enum const TimeUnit." + name);
- }
-
- /**
- * The ordinal of this unit. This is useful both for {@link #ordinal()}
- * and to maintain serialization consistence with earlier versions.
- */
- private final int index;
-
- /** name of this unit */
- private final String name;
-
- /** Internal constructor */
- TimeUnit(int index, String name) {
- this.index = index;
- this.name = name;
- }
-
- // Handy constants for conversion methods
- static final long C0 = 1;
- static final long C1 = C0 * 1000;
- static final long C2 = C1 * 1000;
- static final long C3 = C2 * 1000;
- static final long C4 = C3 * 60;
- static final long C5 = C4 * 60;
- static final long C6 = C5 * 24;
-
- static final long MAX = Long.MAX_VALUE;
-
- /**
- * Scale d by m, checking for overflow.
- * This has a short name to make above code more readable.
- */
- static long x(long d, long m, long over) {
- if (d > over) return Long.MAX_VALUE;
- if (d < -over) return Long.MIN_VALUE;
- return d * m;
- }
-
- /**
- * Convert the given time duration in the given unit to this
- * unit. Conversions from finer to coarser granularities
- * truncate, so lose precision. For example converting
- * <tt>999</tt> milliseconds to seconds results in
- * <tt>0</tt>. Conversions from coarser to finer granularities
- * with arguments that would numerically overflow saturate to
- * <tt>Long.MIN_VALUE</tt> if negative or <tt>Long.MAX_VALUE</tt>
- * if positive.
- *
- * <p>For example, to convert 10 minutes to milliseconds, use:
- * <tt>TimeUnit.MILLISECONDS.convert(10L, TimeUnit.MINUTES)</tt>
- *
- * @param sourceDuration the time duration in the given <tt>sourceUnit</tt>
- * @param sourceUnit the unit of the <tt>sourceDuration</tt> argument
- * @return the converted duration in this unit,
- * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
- * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
- */
- public abstract long convert(long sourceDuration, TimeUnit sourceUnit);
-
- /**
- * Equivalent to <tt>NANOSECONDS.convert(duration, this)</tt>.
- * @param duration the duration
- * @return the converted duration,
- * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
- * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
- * @see #convert
- */
- public abstract long toNanos(long duration);
-
- /**
- * Equivalent to <tt>MICROSECONDS.convert(duration, this)</tt>.
- * @param duration the duration
- * @return the converted duration,
- * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
- * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
- * @see #convert
- */
- public abstract long toMicros(long duration);
-
- /**
- * Equivalent to <tt>MILLISECONDS.convert(duration, this)</tt>.
- * @param duration the duration
- * @return the converted duration,
- * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
- * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
- * @see #convert
- */
- public abstract long toMillis(long duration);
-
- /**
- * Equivalent to <tt>SECONDS.convert(duration, this)</tt>.
- * @param duration the duration
- * @return the converted duration,
- * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
- * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
- * @see #convert
- */
- public abstract long toSeconds(long duration);
-
- /**
- * Equivalent to <tt>MINUTES.convert(duration, this)</tt>.
- * @param duration the duration
- * @return the converted duration,
- * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
- * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
- * @see #convert
- * @since 1.6
- */
- public abstract long toMinutes(long duration);
-
- /**
- * Equivalent to <tt>HOURS.convert(duration, this)</tt>.
- * @param duration the duration
- * @return the converted duration,
- * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
- * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
- * @see #convert
- * @since 1.6
- */
- public abstract long toHours(long duration);
-
- /**
- * Equivalent to <tt>DAYS.convert(duration, this)</tt>.
- * @param duration the duration
- * @return the converted duration
- * @see #convert
- * @since 1.6
- */
- public abstract long toDays(long duration);
-
- /**
- * Utility to compute the excess-nanosecond argument to wait,
- * sleep, join.
- * @param d the duration
- * @param m the number of milliseconds
- * @return the number of nanoseconds
- */
- abstract int excessNanos(long d, long m);
-
- /**
- * Returns the name of this enum constant, exactly as declared in its enum
- * declaration. <strong>Most programmers should use the
- * {@link #toString()} method in preference to this one, as the toString
- * method may return a more user-friendly name.</strong> This method is
- * designed primarily for use in specialized situations where correctness
- * depends on getting the exact name, which will not vary from release to
- * release.
- *
- * @return the name of this enum constant
- */
- public String name() {
- return name;
- }
-
- /**
- * Returns the ordinal of this enumeration constant (its position in its
- * enum declaration, where the initial constant is assigned an ordinal of
- * zero). Most programmers will have no use for this method. It is
- * designed for use by sophisticated enum-based data structures, such as
- * <code>EnumSet</code> and <code>EnumMap</code>.
- *
- * @return the ordinal of this enumeration constant
- */
- public int ordinal() {
- return index;
- }
-
- /*
- * Guarantees that deserialized objects will be referentially equal to the
- * standard enumeration objects.
- */
- protected Object readResolve() throws ObjectStreamException {
- try {
- return valueOf(name);
- } catch (IllegalArgumentException e) {
- throw new InvalidObjectException(name
- + " is not a valid enum for TimeUnit");
- }
- }
-
- /**
- * Performs a timed <tt>Object.wait</tt> using this time unit.
- * This is a convenience method that converts timeout arguments
- * into the form required by the <tt>Object.wait</tt> method.
- *
- * <p>For example, you could implement a blocking <tt>poll</tt>
- * method (see {@link BlockingQueue#poll BlockingQueue.poll})
- * using:
- *
- * <pre> public synchronized Object poll(long timeout, TimeUnit unit) throws InterruptedException {
- * while (empty) {
- * unit.timedWait(this, timeout);
- * ...
- * }
- * }</pre>
- *
- * @param obj the object to wait on
- * @param timeout the maximum time to wait. If less than
- * or equal to zero, do not wait at all.
- * @throws InterruptedException if interrupted while waiting.
- * @see java.lang.Object#wait(long, int)
- */
- public void timedWait(Object obj, long timeout)
- throws InterruptedException {
- if (timeout > 0) {
- long ms = toMillis(timeout);
- int ns = excessNanos(timeout, ms);
- obj.wait(ms, ns);
- }
- }
-
- /**
- * Performs a timed <tt>Thread.join</tt> using this time unit.
- * This is a convenience method that converts time arguments into the
- * form required by the <tt>Thread.join</tt> method.
- * @param thread the thread to wait for
- * @param timeout the maximum time to wait. If less than
- * or equal to zero, do not wait at all.
- * @throws InterruptedException if interrupted while waiting.
- * @see java.lang.Thread#join(long, int)
- */
- public void timedJoin(Thread thread, long timeout)
- throws InterruptedException {
- if (timeout > 0) {
- long ms = toMillis(timeout);
- int ns = excessNanos(timeout, ms);
- thread.join(ms, ns);
- }
- }
-
- /**
- * Performs a <tt>Thread.sleep</tt> using this unit.
- * This is a convenience method that converts time arguments into the
- * form required by the <tt>Thread.sleep</tt> method.
- * @param timeout the maximum time to sleep. If less than
- * or equal to zero, do not sleep at all.
- * @throws InterruptedException if interrupted while sleeping.
- * @see java.lang.Thread#sleep
- */
- public void sleep(long timeout) throws InterruptedException {
- if (timeout > 0) {
- long ms = toMillis(timeout);
- int ns = excessNanos(timeout, ms);
- Thread.sleep(ms, ns);
- }
- }
-
- public String toString() {
- return name;
- }
-}
diff --git a/src/actors/scala/actors/threadpool/TimeoutException.java b/src/actors/scala/actors/threadpool/TimeoutException.java
deleted file mode 100644
index c6fdbe5dc4..0000000000
--- a/src/actors/scala/actors/threadpool/TimeoutException.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
- */
-
-package scala.actors.threadpool;
-
-/**
- * Exception thrown when a blocking operation times out. Blocking
- * operations for which a timeout is specified need a means to
- * indicate that the timeout has occurred. For many such operations it
- * is possible to return a value that indicates timeout; when that is
- * not possible or desirable then <tt>TimeoutException</tt> should be
- * declared and thrown.
- *
- * @since 1.5
- * @author Doug Lea
- */
-public class TimeoutException extends Exception {
- private static final long serialVersionUID = 1900926677490660714L;
-
- /**
- * Constructs a <tt>TimeoutException</tt> with no specified detail
- * message.
- */
- public TimeoutException() {}
-
- /**
- * Constructs a <tt>TimeoutException</tt> with the specified detail
- * message.
- *
- * @param message the detail message
- */
- public TimeoutException(String message) {
- super(message);
- }
-}
diff --git a/src/actors/scala/actors/threadpool/helpers/FIFOWaitQueue.java b/src/actors/scala/actors/threadpool/helpers/FIFOWaitQueue.java
deleted file mode 100644
index 432b851f3e..0000000000
--- a/src/actors/scala/actors/threadpool/helpers/FIFOWaitQueue.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package scala.actors.threadpool.helpers;
-
-import java.util.Collection;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Simple linked list queue used in FIFOSemaphore.
- * Methods are not synchronized; they depend on synch of callers.
- * Must be public, since it is used by Semaphore (outside this package).
- * NOTE: this class is NOT present in java.util.concurrent.
- **/
-
-public class FIFOWaitQueue extends WaitQueue implements java.io.Serializable {
-
- private final static long serialVersionUID = 2416444691925378811L;
-
- protected transient WaitNode head_ = null;
- protected transient WaitNode tail_ = null;
-
- public FIFOWaitQueue() {}
-
- public void insert(WaitNode w) {
- if (tail_ == null)
- head_ = tail_ = w;
- else {
- tail_.next = w;
- tail_ = w;
- }
- }
-
- public WaitNode extract() {
- if (head_ == null)
- return null;
- else {
- WaitNode w = head_;
- head_ = w.next;
- if (head_ == null)
- tail_ = null;
- w.next = null;
- return w;
- }
- }
-
- public void putBack(WaitNode w) {
- w.next = head_;
- head_ = w;
- if (tail_ == null)
- tail_ = w;
- }
-
- public boolean hasNodes() {
- return head_ != null;
- }
-
- public int getLength() {
- int count = 0;
- WaitNode node = head_;
- while (node != null) {
- if (node.waiting) count++;
- node = node.next;
- }
- return count;
- }
-
- public Collection getWaitingThreads() {
- List<Thread> list = new ArrayList<Thread>();
- int count = 0;
- WaitNode node = head_;
- while (node != null) {
- if (node.waiting) list.add(node.owner);
- node = node.next;
- }
- return list;
- }
-
- public boolean isWaiting(Thread thread) {
- if (thread == null) throw new NullPointerException();
- for (WaitNode node = head_; node != null; node = node.next) {
- if (node.waiting && node.owner == thread) return true;
- }
- return false;
- }
-
-}
diff --git a/src/actors/scala/actors/threadpool/helpers/NanoTimer.java b/src/actors/scala/actors/threadpool/helpers/NanoTimer.java
deleted file mode 100644
index f3edf13565..0000000000
--- a/src/actors/scala/actors/threadpool/helpers/NanoTimer.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Written by Dawid Kurzyniec and released to the public domain, as explained
- * at http://creativecommons.org/licenses/publicdomain
- */
-package scala.actors.threadpool.helpers;
-
-/**
- * Interface to specify custom implementation of precise timer.
- *
- * @author Dawid Kurzyniec
- * @version 1.0
- */
-public interface NanoTimer {
- /**
- * Returns the current value of the most precise available system timer,
- * in nanoseconds. This method can only be used to measure elapsed time and
- * is not related to any other notion of system or wall-clock time. The
- * value returned represents nanoseconds since some fixed but arbitrary
- * time (perhaps in the future, so values may be negative). This method
- * provides nanosecond precision, but not necessarily nanosecond accuracy.
- * No guarantees are made about how frequently values change. Differences
- * in successive calls that span greater than approximately 292 years
- * (263 nanoseconds) will not accurately compute elapsed time due to
- * numerical overflow.
- *
- * @return The current value of the system timer, in nanoseconds.
- */
- long nanoTime();
-}
diff --git a/src/actors/scala/actors/threadpool/helpers/ThreadHelpers.java b/src/actors/scala/actors/threadpool/helpers/ThreadHelpers.java
deleted file mode 100644
index 13da20c4d6..0000000000
--- a/src/actors/scala/actors/threadpool/helpers/ThreadHelpers.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Written by Dawid Kurzyniec and released to the public domain, as explained
- * at http://creativecommons.org/licenses/publicdomain
- */
-package scala.actors.threadpool.helpers;
-
-/**
- * Emulation of some new functionality present in java.lang.Thread in J2SE 5.0.
- *
- * @author Dawid Kurzyniec
- * @version 1.0
- */
-public class ThreadHelpers {
-
- private ThreadHelpers() {}
-
- /**
- * Returns wrapped runnable that ensures that if an exception occurs
- * during the execution, the specified exception handler is invoked.
- * @param runnable runnable for which exceptions are to be intercepted
- * @param handler the exception handler to call when exception occurs
- * during execution of the given runnable
- * @return wrapped runnable
- */
- public static Runnable assignExceptionHandler(final Runnable runnable,
- final UncaughtExceptionHandler handler)
- {
- if (runnable == null || handler == null) {
- throw new NullPointerException();
- }
- return new Runnable() {
- public void run() {
- try {
- runnable.run();
- }
- catch (Throwable error) {
- try {
- handler.uncaughtException(Thread.currentThread(), error);
- }
- catch (Throwable ignore) {}
- }
- }
- };
- }
-
- /**
- * Abstraction of the exception handler which receives notifications of
- * exceptions occurred possibly in various parts of the system. Exception
- * handlers present attractive approach to exception handling in multi-threaded
- * systems, as they can handle exceptions that occurred in different threads.
- * <p>
- * This class is analogous to Thread.UncaughtExceptionHandler in J2SE 5.0.
- * Obviously you cannot use it the same way, e.g. you cannot assign the
- * handler to the thread so that it is invoked when thread terminates.
- * However, it can be {@link ThreadHelpers#assignExceptionHandler emulated}.
- */
- public static interface UncaughtExceptionHandler {
- /**
- * Notification of the uncaught exception that occurred within specified
- * thread.
- * @param thread the thread where the exception occurred
- * @param error the exception
- */
- void uncaughtException(Thread thread, Throwable error);
- }
-}
diff --git a/src/actors/scala/actors/threadpool/helpers/Utils.java b/src/actors/scala/actors/threadpool/helpers/Utils.java
deleted file mode 100644
index d12389215d..0000000000
--- a/src/actors/scala/actors/threadpool/helpers/Utils.java
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * Written by Dawid Kurzyniec, based on code written by Doug Lea with assistance
- * from members of JCP JSR-166 Expert Group. Released to the public domain,
- * as explained at http://creativecommons.org/licenses/publicdomain.
- *
- * Thanks to Craig Mattocks for suggesting to use <code>sun.misc.Perf</code>.
- */
-
-package scala.actors.threadpool.helpers;
-
-//import edu.emory.mathcs.backport.java.util.*;
-import scala.actors.threadpool.*;
-import scala.actors.threadpool.locks.*;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.lang.reflect.Array;
-import java.util.Iterator;
-import java.util.Collection;
-
-/**
- * <p>
- * This class groups together the functionality of java.util.concurrent that
- * cannot be fully and reliably implemented in backport, but for which some
- * form of emulation is possible.
- * <p>
- * Currently, this class contains methods related to nanosecond-precision
- * timing, particularly via the {@link #nanoTime} method. To measure time
- * accurately, this method by default uses <code>java.sun.Perf</code> on
- * JDK1.4.2 and it falls back to <code>System.currentTimeMillis</code>
- * on earlier JDKs.
- *
- * @author Dawid Kurzyniec
- * @version 1.0
- */
-public final class Utils {
-
- private final static NanoTimer nanoTimer;
- private final static String providerProp =
- "edu.emory.mathcs.backport.java.util.concurrent.NanoTimerProvider";
-
- static {
- NanoTimer timer = null;
- try {
- String nanoTimerClassName =
- AccessController.doPrivileged(new PrivilegedAction<String>() {
- public String run() {
- return System.getProperty(providerProp);
- }
- });
- if (nanoTimerClassName != null) {
- Class cls = Class.forName(nanoTimerClassName);
- timer = (NanoTimer) cls.newInstance();
- }
- }
- catch (Exception e) {
- System.err.println("WARNING: unable to load the system-property-defined " +
- "nanotime provider; switching to the default");
- e.printStackTrace();
- }
-
- if (timer == null) {
- try {
- timer = new SunPerfProvider();
- }
- catch (Throwable e) {}
- }
-
- if (timer == null) {
- timer = new MillisProvider();
- }
-
- nanoTimer = timer;
- }
-
- private Utils() {}
-
- /**
- * Returns the current value of the most precise available system timer,
- * in nanoseconds. This method can only be used to measure elapsed time and
- * is not related to any other notion of system or wall-clock time. The
- * value returned represents nanoseconds since some fixed but arbitrary
- * time (perhaps in the future, so values may be negative). This method
- * provides nanosecond precision, but not necessarily nanosecond accuracy.
- * No guarantees are made about how frequently values change. Differences
- * in successive calls that span greater than approximately 292 years
- * (2^63 nanoseconds) will not accurately compute elapsed time due to
- * numerical overflow.
- * <p>
- * <em>Implementation note:</em>By default, this method uses
- * <code>sun.misc.Perf</code> on Java 1.4.2, and falls back to
- * System.currentTimeMillis() emulation on earlier JDKs. Custom
- * timer can be provided via the system property
- * <code>edu.emory.mathcs.backport.java.util.concurrent.NanoTimerProvider</code>.
- * The value of the property should name a class implementing
- * {@link NanoTimer} interface.
- * <p>
- * Note: on JDK 1.4.2, <code>sun.misc.Perf</code> timer seems to have
- * resolution of the order of 1 microsecond, measured on Linux.
- *
- * @return The current value of the system timer, in nanoseconds.
- */
- public static long nanoTime() {
- return nanoTimer.nanoTime();
- }
-
- /**
- * Causes the current thread to wait until it is signalled or interrupted,
- * or the specified waiting time elapses. This method originally appears
- * in the {@link Condition} interface, but it was moved to here since it
- * can only be emulated, with very little accuracy guarantees: the
- * efficient implementation requires accurate nanosecond timer and native
- * support for nanosecond-precision wait queues, which are not usually
- * present in JVMs prior to 1.5. Loss of precision may cause total waiting
- * times to be systematically shorter than specified when re-waits occur.
- *
- * <p>The lock associated with this condition is atomically
- * released and the current thread becomes disabled for thread scheduling
- * purposes and lies dormant until <em>one</em> of five things happens:
- * <ul>
- * <li>Some other thread invokes the {@link
- * edu.emory.mathcs.backport.java.util.concurrent.locks.Condition#signal}
- * method for this
- * <tt>Condition</tt> and the current thread happens to be chosen as the
- * thread to be awakened; or
- * <li>Some other thread invokes the {@link
- * edu.emory.mathcs.backport.java.util.concurrent.locks.Condition#signalAll}
- * method for this
- * <tt>Condition</tt>; or
- * <li>Some other thread {@link Thread#interrupt interrupts} the current
- * thread, and interruption of thread suspension is supported; or
- * <li>The specified waiting time elapses; or
- * <li>A &quot;<em>spurious wakeup</em>&quot; occurs.
- * </ul>
- *
- * <p>In all cases, before this method can return the current thread must
- * re-acquire the lock associated with this condition. When the
- * thread returns it is <em>guaranteed</em> to hold this lock.
- *
- * <p>If the current thread:
- * <ul>
- * <li>has its interrupted status set on entry to this method; or
- * <li>is {@link Thread#interrupt interrupted} while waiting
- * and interruption of thread suspension is supported,
- * </ul>
- * then {@link InterruptedException} is thrown and the current thread's
- * interrupted status is cleared. It is not specified, in the first
- * case, whether or not the test for interruption occurs before the lock
- * is released.
- *
- * <p>The method returns an estimate of the number of nanoseconds
- * remaining to wait given the supplied <tt>nanosTimeout</tt>
- * value upon return, or a value less than or equal to zero if it
- * timed out. Accuracy of this estimate is directly dependent on the
- * accuracy of {@link #nanoTime}. This value can be used to determine
- * whether and how long to re-wait in cases where the wait returns but an
- * awaited condition still does not hold. Typical uses of this method take
- * the following form:
- *
- * <pre>
- * synchronized boolean aMethod(long timeout, TimeUnit unit) {
- * long nanosTimeout = unit.toNanos(timeout);
- * while (!conditionBeingWaitedFor) {
- * if (nanosTimeout &gt; 0)
- * nanosTimeout = theCondition.awaitNanos(nanosTimeout);
- * else
- * return false;
- * }
- * // ...
- * }
- * </pre>
- *
- * <p><b>Implementation Considerations</b>
- * <p>The current thread is assumed to hold the lock associated with this
- * <tt>Condition</tt> when this method is called.
- * It is up to the implementation to determine if this is
- * the case and if not, how to respond. Typically, an exception will be
- * thrown (such as {@link IllegalMonitorStateException}) and the
- * implementation must document that fact.
- *
- * <p>A condition implementation can favor responding to an interrupt over
- * normal method return in response to a signal, or over indicating the
- * elapse of the specified waiting time. In either case the implementation
- * must ensure that the signal is redirected to another waiting thread, if
- * there is one.
- *
- * @param cond the condition to wait for
- * @param nanosTimeout the maximum time to wait, in nanoseconds
- * @return A value less than or equal to zero if the wait has
- * timed out; otherwise an estimate, that
- * is strictly less than the <tt>nanosTimeout</tt> argument,
- * of the time still remaining when this method returned.
- *
- * @throws InterruptedException if the current thread is interrupted (and
- * interruption of thread suspension is supported).
- */
- public static long awaitNanos(Condition cond, long nanosTimeout)
- throws InterruptedException
- {
- if (nanosTimeout <= 0) return nanosTimeout;
- long now = nanoTime();
- cond.await(nanosTimeout, TimeUnit.NANOSECONDS);
- return nanosTimeout - (nanoTime() - now);
- }
-
- private static final class SunPerfProvider implements NanoTimer {
- final Perf perf;
- final long multiplier, divisor;
- SunPerfProvider() {
- perf =
- AccessController.doPrivileged(new PrivilegedAction<Perf>() {
- public Perf run() {
- return Perf.getPerf();
- }
- });
- // trying to avoid BOTH overflow and rounding errors
- long numerator = 1000000000;
- long denominator = perf.highResFrequency();
- long gcd = gcd(numerator, denominator);
- this.multiplier = numerator / gcd;
- this.divisor = denominator / gcd;
- }
- public long nanoTime() {
- long ctr = perf.highResCounter();
-
- // anything less sophisticated suffers either from rounding errors
- // (FP arithmetics, backport v1.0) or overflow, when gcd is small
- // (a bug in backport v1.0_01 reported by Ramesh Nethi)
-
- return ((ctr / divisor) * multiplier) +
- (ctr % divisor) * multiplier / divisor;
-
- // even the above can theoretically cause problems if your JVM is
- // running for sufficiently long time, but "sufficiently" means 292
- // years (worst case), or 30,000 years (common case).
-
- // Details: when the ticks ctr overflows, there is no way to avoid
- // discontinuity in computed nanos, even in infinite arithmetics,
- // unless we count number of overflows that the ctr went through
- // since the JVM started. This follows from the fact that
- // (2^64*multiplier/divisor) mod (2^64) > 0 in general case.
- // Theoretically we could find out the number of overflows by
- // checking System.currentTimeMillis(), but this is unreliable
- // since the system time can unpredictably change during the JVM
- // lifetime.
- // The time to overflow is 2^63 / ticks frequency. With current
- // ticks frequencies of several MHz, it gives about 30,000 years
- // before the problem happens. If ticks frequency reaches 1 GHz, the
- // time to overflow is 292 years. It is unlikely that the frequency
- // ever exceeds 1 GHz. We could double the time to overflow
- // (to 2^64 / frequency) by using unsigned arithmetics, e.g. by
- // adding the following correction whenever the ticks is negative:
- // -2*((Long.MIN_VALUE / divisor) * multiplier +
- // (Long.MIN_VALUE % divisor) * multiplier / divisor)
- // But, with the worst case of as much as 292 years, it does not
- // seem justified.
- }
- }
-
- private static final class MillisProvider implements NanoTimer {
- MillisProvider() {}
- public long nanoTime() {
- return System.currentTimeMillis() * 1000000;
- }
- }
-
- private static long gcd(long a, long b) {
- long r;
- while (b>0) { r = a % b; a = b; b = r; }
- return a;
- }
-
-
- public static Object[] collectionToArray(Collection c) {
- // guess the array size; expect to possibly be different
- int len = c.size();
- Object[] arr = new Object[len];
- Iterator itr = c.iterator();
- int idx = 0;
- while (true) {
- while (idx < len && itr.hasNext()) {
- arr[idx++] = itr.next();
- }
- if (!itr.hasNext()) {
- if (idx == len) return arr;
- // otherwise have to trim
- return Arrays.copyOf(arr, idx, Object[].class);
- }
- // otherwise, have to grow
- int newcap = ((arr.length/2)+1)*3;
- if (newcap < arr.length) {
- // overflow
- if (arr.length < Integer.MAX_VALUE) {
- newcap = Integer.MAX_VALUE;
- }
- else {
- throw new OutOfMemoryError("required array size too large");
- }
- }
- arr = Arrays.copyOf(arr, newcap, Object[].class);
- len = newcap;
- }
- }
-
- public static Object[] collectionToArray(Collection c, Object[] a) {
- Class aType = a.getClass();
- // guess the array size; expect to possibly be different
- int len = c.size();
- Object[] arr = (a.length >= len ? a :
- (Object[])Array.newInstance(aType.getComponentType(), len));
- Iterator itr = c.iterator();
- int idx = 0;
- while (true) {
- while (idx < len && itr.hasNext()) {
- arr[idx++] = itr.next();
- }
- if (!itr.hasNext()) {
- if (idx == len) return arr;
- if (arr == a) {
- // orig array -> null terminate
- a[idx] = null;
- return a;
- }
- else {
- // have to trim
- return Arrays.copyOf(arr, idx, aType);
- }
- }
- // otherwise, have to grow
- int newcap = ((arr.length/2)+1)*3;
- if (newcap < arr.length) {
- // overflow
- if (arr.length < Integer.MAX_VALUE) {
- newcap = Integer.MAX_VALUE;
- }
- else {
- throw new OutOfMemoryError("required array size too large");
- }
- }
- arr = Arrays.copyOf(arr, newcap, aType);
- len = newcap;
- }
- }
-}
diff --git a/src/actors/scala/actors/threadpool/helpers/WaitQueue.java b/src/actors/scala/actors/threadpool/helpers/WaitQueue.java
deleted file mode 100644
index bcbf29e5c2..0000000000
--- a/src/actors/scala/actors/threadpool/helpers/WaitQueue.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- based on file: QueuedSemaphore.java
- Originally written by Doug Lea and released into the public domain.
- This may be used for any purposes whatsoever without acknowledgment.
- Thanks for the assistance and support of Sun Microsystems Labs,
- and everyone contributing, testing, and using this code.
- History:
- Date Who What
- 11Jun1998 dl Create public version
- 5Aug1998 dl replaced int counters with longs
- 24Aug1999 dl release(n): screen arguments
- */
-
-package scala.actors.threadpool.helpers;
-
-import java.util.Collection;
-import scala.actors.threadpool.*;
-
-/**
- * Base class for internal queue classes for semaphores, etc.
- * Relies on subclasses to actually implement queue mechanics.
- * NOTE: this class is NOT present in java.util.concurrent.
- **/
-
-public abstract class WaitQueue {
-
- public abstract void insert(WaitNode w); // assumed not to block
- public abstract WaitNode extract(); // should return null if empty
- public abstract void putBack(WaitNode w);
-
- public abstract boolean hasNodes();
- public abstract int getLength();
- public abstract Collection getWaitingThreads();
- public abstract boolean isWaiting(Thread thread);
-
- public static interface QueuedSync {
- // invoked with sync on wait node, (atomically) just before enqueuing
- boolean recheck(WaitNode node);
- // invoked with sync on wait node, (atomically) just before signalling
- void takeOver(WaitNode node);
- }
-
- public static class WaitNode {
- boolean waiting = true;
- WaitNode next = null;
- final Thread owner;
-
- public WaitNode() {
- this.owner = Thread.currentThread();
- }
-
- public Thread getOwner() {
- return owner;
- }
-
- public synchronized boolean signal(QueuedSync sync) {
- boolean signalled = waiting;
- if (signalled) {
- waiting = false;
- notify();
- sync.takeOver(this);
- }
- return signalled;
- }
-
- public synchronized boolean doTimedWait(QueuedSync sync, long nanos)
- throws InterruptedException
- {
- if (sync.recheck(this) || !waiting)
- return true;
- else if (nanos <= 0) {
- waiting = false;
- return false;
- }
- else {
- long deadline = Utils.nanoTime() + nanos;
- try {
- for (; ; ) {
- TimeUnit.NANOSECONDS.timedWait(this, nanos);
- if (!waiting) // definitely signalled
- return true;
- else {
- nanos = deadline - Utils.nanoTime();
- if (nanos <= 0) { // timed out
- waiting = false;
- return false;
- }
- }
- }
- }
- catch (InterruptedException ex) {
- if (waiting) { // no notification
- waiting = false; // invalidate for the signaller
- throw ex;
- }
- else { // thread was interrupted after it was notified
- Thread.currentThread().interrupt();
- return true;
- }
- }
- }
- }
-
- public synchronized void doWait(QueuedSync sync)
- throws InterruptedException
- {
- if (!sync.recheck(this)) {
- try {
- while (waiting) wait();
- }
- catch (InterruptedException ex) {
- if (waiting) { // no notification
- waiting = false; // invalidate for the signaller
- throw ex;
- }
- else { // thread was interrupted after it was notified
- Thread.currentThread().interrupt();
- return;
- }
- }
- }
- }
-
- public synchronized void doWaitUninterruptibly(QueuedSync sync) {
- if (!sync.recheck(this)) {
- boolean wasInterrupted = Thread.interrupted();
- try {
- while (waiting) {
- try {
- wait();
- }
- catch (InterruptedException ex) {
- wasInterrupted = true;
- // no need to notify; if we were signalled, we
- // must be not waiting, and we'll act like signalled
- }
- }
- }
- finally {
- if (wasInterrupted) Thread.currentThread().interrupt();
- }
- }
- }
- }
-}
-
diff --git a/src/actors/scala/actors/threadpool/locks/CondVar.java b/src/actors/scala/actors/threadpool/locks/CondVar.java
deleted file mode 100644
index 44df1c0b97..0000000000
--- a/src/actors/scala/actors/threadpool/locks/CondVar.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- File: ConditionVariable.java
- Originally written by Doug Lea and released into the public domain.
- This may be used for any purposes whatsoever without acknowledgment.
- Thanks for the assistance and support of Sun Microsystems Labs,
- and everyone contributing, testing, and using this code.
- History:
- Date Who What
- 11Jun1998 dl Create public version
- */
-
-package scala.actors.threadpool.locks;
-
-import java.util.Collection;
-import java.util.Date;
-import scala.actors.threadpool.*;
-import scala.actors.threadpool.helpers.*;
-
-class CondVar implements Condition, java.io.Serializable {
- private static final long serialVersionUID = -5009898475638427940L;
-
- /** The lock **/
- protected final ExclusiveLock lock;
-
- /**
- * Create a new CondVar that relies on the given mutual
- * exclusion lock.
- * @param lock A non-reentrant mutual exclusion lock.
- **/
-
- CondVar(ExclusiveLock lock) {
- this.lock = lock;
- }
-
- public void awaitUninterruptibly() {
- int holdCount = lock.getHoldCount();
- if (holdCount == 0) {
- throw new IllegalMonitorStateException();
- }
- // avoid instant spurious wakeup if thread already interrupted
- boolean wasInterrupted = Thread.interrupted();
- try {
- synchronized (this) {
- for (int i=holdCount; i>0; i--) lock.unlock();
- try {
- wait();
- }
- catch (InterruptedException ex) {
- wasInterrupted = true;
- // may have masked the signal and there is no way
- // to tell; we must wake up spuriously
- }
- }
- }
- finally {
- for (int i=holdCount; i>0; i--) lock.lock();
- if (wasInterrupted) {
- Thread.currentThread().interrupt();
- }
- }
- }
-
- public void await() throws InterruptedException {
- int holdCount = lock.getHoldCount();
- if (holdCount == 0) {
- throw new IllegalMonitorStateException();
- }
- if (Thread.interrupted()) throw new InterruptedException();
- try {
- synchronized (this) {
- for (int i=holdCount; i>0; i--) lock.unlock();
- try {
- wait();
- }
- catch (InterruptedException ex) {
- notify();
- throw ex;
- }
- }
- }
- finally {
- for (int i=holdCount; i>0; i--) lock.lock();
- }
- }
-
- public boolean await(long timeout, TimeUnit unit) throws InterruptedException {
- int holdCount = lock.getHoldCount();
- if (holdCount == 0) {
- throw new IllegalMonitorStateException();
- }
- if (Thread.interrupted()) throw new InterruptedException();
- long nanos = unit.toNanos(timeout);
- boolean success = false;
- try {
- synchronized (this) {
- for (int i=holdCount; i>0; i--) lock.unlock();
- try {
- if (nanos > 0) {
- long start = Utils.nanoTime();
- TimeUnit.NANOSECONDS.timedWait(this, nanos);
- // DK: due to coarse-grained (millis) clock, it seems
- // preferable to acknowledge timeout (success == false)
- // when the equality holds (timing is exact)
- success = Utils.nanoTime() - start < nanos;
- }
- }
- catch (InterruptedException ex) {
- notify();
- throw ex;
- }
- }
- }
- finally {
- for (int i=holdCount; i>0; i--) lock.lock();
- }
- return success;
- }
-
-// public long awaitNanos(long timeout) throws InterruptedException {
-// throw new UnsupportedOperationException();
-// }
-//
- public boolean awaitUntil(Date deadline) throws InterruptedException {
- if (deadline == null) throw new NullPointerException();
- int holdCount = lock.getHoldCount();
- if (holdCount == 0) {
- throw new IllegalMonitorStateException();
- }
- long abstime = deadline.getTime();
- if (Thread.interrupted()) throw new InterruptedException();
-
- boolean success = false;
- try {
- synchronized (this) {
- for (int i=holdCount; i>0; i--) lock.unlock();
- try {
- long start = System.currentTimeMillis();
- long msecs = abstime - start;
- if (msecs > 0) {
- wait(msecs);
- // DK: due to coarse-grained (millis) clock, it seems
- // preferable to acknowledge timeout (success == false)
- // when the equality holds (timing is exact)
- success = System.currentTimeMillis() - start < msecs;
- }
- }
- catch (InterruptedException ex) {
- notify();
- throw ex;
- }
- }
- }
- finally {
- for (int i=holdCount; i>0; i--) lock.lock();
- }
- return success;
- }
-
- public synchronized void signal() {
- if (!lock.isHeldByCurrentThread()) {
- throw new IllegalMonitorStateException();
- }
- notify();
- }
-
- public synchronized void signalAll() {
- if (!lock.isHeldByCurrentThread()) {
- throw new IllegalMonitorStateException();
- }
- notifyAll();
- }
-
- protected ExclusiveLock getLock() { return lock; }
-
- protected boolean hasWaiters() {
- throw new UnsupportedOperationException("Use FAIR version");
- }
-
- protected int getWaitQueueLength() {
- throw new UnsupportedOperationException("Use FAIR version");
- }
-
- protected Collection getWaitingThreads() {
- throw new UnsupportedOperationException("Use FAIR version");
- }
-
- static interface ExclusiveLock extends Lock {
- boolean isHeldByCurrentThread();
- int getHoldCount();
- }
-}
diff --git a/src/actors/scala/actors/threadpool/locks/Condition.java b/src/actors/scala/actors/threadpool/locks/Condition.java
deleted file mode 100644
index 0553684321..0000000000
--- a/src/actors/scala/actors/threadpool/locks/Condition.java
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
- */
-
-package scala.actors.threadpool.locks;
-
-import scala.actors.threadpool.*;
-import java.util.Date;
-
-/**
- * {@code Condition} factors out the {@code Object} monitor
- * methods ({@link Object#wait() wait}, {@link Object#notify notify}
- * and {@link Object#notifyAll notifyAll}) into distinct objects to
- * give the effect of having multiple wait-sets per object, by
- * combining them with the use of arbitrary {@link Lock} implementations.
- * Where a {@code Lock} replaces the use of {@code synchronized} methods
- * and statements, a {@code Condition} replaces the use of the Object
- * monitor methods.
- *
- * <p>Conditions (also known as <em>condition queues</em> or
- * <em>condition variables</em>) provide a means for one thread to
- * suspend execution (to &quot;wait&quot;) until notified by another
- * thread that some state condition may now be true. Because access
- * to this shared state information occurs in different threads, it
- * must be protected, so a lock of some form is associated with the
- * condition. The key property that waiting for a condition provides
- * is that it <em>atomically</em> releases the associated lock and
- * suspends the current thread, just like {@code Object.wait}.
- *
- * <p>A {@code Condition} instance is intrinsically bound to a lock.
- * To obtain a {@code Condition} instance for a particular {@link Lock}
- * instance use its {@link Lock#newCondition newCondition()} method.
- *
- * <p>As an example, suppose we have a bounded buffer which supports
- * {@code put} and {@code take} methods. If a
- * {@code take} is attempted on an empty buffer, then the thread will block
- * until an item becomes available; if a {@code put} is attempted on a
- * full buffer, then the thread will block until a space becomes available.
- * We would like to keep waiting {@code put} threads and {@code take}
- * threads in separate wait-sets so that we can use the optimization of
- * only notifying a single thread at a time when items or spaces become
- * available in the buffer. This can be achieved using two
- * {@link Condition} instances.
- * <pre>
- * class BoundedBuffer {
- * <b>final Lock lock = new ReentrantLock();</b>
- * final Condition notFull = <b>lock.newCondition(); </b>
- * final Condition notEmpty = <b>lock.newCondition(); </b>
- *
- * final Object[] items = new Object[100];
- * int putptr, takeptr, count;
- *
- * public void put(Object x) throws InterruptedException {
- * <b>lock.lock();
- * try {</b>
- * while (count == items.length)
- * <b>notFull.await();</b>
- * items[putptr] = x;
- * if (++putptr == items.length) putptr = 0;
- * ++count;
- * <b>notEmpty.signal();</b>
- * <b>} finally {
- * lock.unlock();
- * }</b>
- * }
- *
- * public Object take() throws InterruptedException {
- * <b>lock.lock();
- * try {</b>
- * while (count == 0)
- * <b>notEmpty.await();</b>
- * Object x = items[takeptr];
- * if (++takeptr == items.length) takeptr = 0;
- * --count;
- * <b>notFull.signal();</b>
- * return x;
- * <b>} finally {
- * lock.unlock();
- * }</b>
- * }
- * }
- * </pre>
- *
- * (The {@link edu.emory.mathcs.backport.java.util.concurrent.ArrayBlockingQueue} class provides
- * this functionality, so there is no reason to implement this
- * sample usage class.)
- *
- * <p>A {@code Condition} implementation can provide behavior and semantics
- * that is
- * different from that of the {@code Object} monitor methods, such as
- * guaranteed ordering for notifications, or not requiring a lock to be held
- * when performing notifications.
- * If an implementation provides such specialized semantics then the
- * implementation must document those semantics.
- *
- * <p>Note that {@code Condition} instances are just normal objects and can
- * themselves be used as the target in a {@code synchronized} statement,
- * and can have their own monitor {@link Object#wait wait} and
- * {@link Object#notify notification} methods invoked.
- * Acquiring the monitor lock of a {@code Condition} instance, or using its
- * monitor methods, has no specified relationship with acquiring the
- * {@link Lock} associated with that {@code Condition} or the use of its
- * {@linkplain #await waiting} and {@linkplain #signal signalling} methods.
- * It is recommended that to avoid confusion you never use {@code Condition}
- * instances in this way, except perhaps within their own implementation.
- *
- * <p>Except where noted, passing a {@code null} value for any parameter
- * will result in a {@link NullPointerException} being thrown.
- *
- * <h3>Implementation Considerations</h3>
- *
- * <p>When waiting upon a {@code Condition}, a &quot;<em>spurious
- * wakeup</em>&quot; is permitted to occur, in
- * general, as a concession to the underlying platform semantics.
- * This has little practical impact on most application programs as a
- * {@code Condition} should always be waited upon in a loop, testing
- * the state predicate that is being waited for. An implementation is
- * free to remove the possibility of spurious wakeups but it is
- * recommended that applications programmers always assume that they can
- * occur and so always wait in a loop.
- *
- * <p>The three forms of condition waiting
- * (interruptible, non-interruptible, and timed) may differ in their ease of
- * implementation on some platforms and in their performance characteristics.
- * In particular, it may be difficult to provide these features and maintain
- * specific semantics such as ordering guarantees.
- * Further, the ability to interrupt the actual suspension of the thread may
- * not always be feasible to implement on all platforms.
- *
- * <p>Consequently, an implementation is not required to define exactly the
- * same guarantees or semantics for all three forms of waiting, nor is it
- * required to support interruption of the actual suspension of the thread.
- *
- * <p>An implementation is required to
- * clearly document the semantics and guarantees provided by each of the
- * waiting methods, and when an implementation does support interruption of
- * thread suspension then it must obey the interruption semantics as defined
- * in this interface.
- *
- * <p>As interruption generally implies cancellation, and checks for
- * interruption are often infrequent, an implementation can favor responding
- * to an interrupt over normal method return. This is true even if it can be
- * shown that the interrupt occurred after another action may have unblocked
- * the thread. An implementation should document this behavior.
- *
- * @since 1.5
- * @author Doug Lea
- */
-public interface Condition {
-
- /**
- * Causes the current thread to wait until it is signalled or
- * {@linkplain Thread#interrupt interrupted}.
- *
- * <p>The lock associated with this {@code Condition} is atomically
- * released and the current thread becomes disabled for thread scheduling
- * purposes and lies dormant until <em>one</em> of four things happens:
- * <ul>
- * <li>Some other thread invokes the {@link #signal} method for this
- * {@code Condition} and the current thread happens to be chosen as the
- * thread to be awakened; or
- * <li>Some other thread invokes the {@link #signalAll} method for this
- * {@code Condition}; or
- * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
- * current thread, and interruption of thread suspension is supported; or
- * <li>A &quot;<em>spurious wakeup</em>&quot; occurs.
- * </ul>
- *
- * <p>In all cases, before this method can return the current thread must
- * re-acquire the lock associated with this condition. When the
- * thread returns it is <em>guaranteed</em> to hold this lock.
- *
- * <p>If the current thread:
- * <ul>
- * <li>has its interrupted status set on entry to this method; or
- * <li>is {@linkplain Thread#interrupt interrupted} while waiting
- * and interruption of thread suspension is supported,
- * </ul>
- * then {@link InterruptedException} is thrown and the current thread's
- * interrupted status is cleared. It is not specified, in the first
- * case, whether or not the test for interruption occurs before the lock
- * is released.
- *
- * <p><b>Implementation Considerations</b>
- *
- * <p>The current thread is assumed to hold the lock associated with this
- * {@code Condition} when this method is called.
- * It is up to the implementation to determine if this is
- * the case and if not, how to respond. Typically, an exception will be
- * thrown (such as {@link IllegalMonitorStateException}) and the
- * implementation must document that fact.
- *
- * <p>An implementation can favor responding to an interrupt over normal
- * method return in response to a signal. In that case the implementation
- * must ensure that the signal is redirected to another waiting thread, if
- * there is one.
- *
- * @throws InterruptedException if the current thread is interrupted
- * (and interruption of thread suspension is supported)
- */
- void await() throws InterruptedException;
-
- /**
- * Causes the current thread to wait until it is signalled.
- *
- * <p>The lock associated with this condition is atomically
- * released and the current thread becomes disabled for thread scheduling
- * purposes and lies dormant until <em>one</em> of three things happens:
- * <ul>
- * <li>Some other thread invokes the {@link #signal} method for this
- * {@code Condition} and the current thread happens to be chosen as the
- * thread to be awakened; or
- * <li>Some other thread invokes the {@link #signalAll} method for this
- * {@code Condition}; or
- * <li>A &quot;<em>spurious wakeup</em>&quot; occurs.
- * </ul>
- *
- * <p>In all cases, before this method can return the current thread must
- * re-acquire the lock associated with this condition. When the
- * thread returns it is <em>guaranteed</em> to hold this lock.
- *
- * <p>If the current thread's interrupted status is set when it enters
- * this method, or it is {@linkplain Thread#interrupt interrupted}
- * while waiting, it will continue to wait until signalled. When it finally
- * returns from this method its interrupted status will still
- * be set.
- *
- * <p><b>Implementation Considerations</b>
- *
- * <p>The current thread is assumed to hold the lock associated with this
- * {@code Condition} when this method is called.
- * It is up to the implementation to determine if this is
- * the case and if not, how to respond. Typically, an exception will be
- * thrown (such as {@link IllegalMonitorStateException}) and the
- * implementation must document that fact.
- */
- void awaitUninterruptibly();
-
-// /**
-// * Causes the current thread to wait until it is signalled or interrupted,
-// * or the specified waiting time elapses.
-// *
-// * <p>The lock associated with this condition is atomically
-// * released and the current thread becomes disabled for thread scheduling
-// * purposes and lies dormant until <em>one</em> of five things happens:
-// * <ul>
-// * <li>Some other thread invokes the {@link #signal} method for this
-// * <tt>Condition</tt> and the current thread happens to be chosen as the
-// * thread to be awakened; or
-// * <li>Some other thread invokes the {@link #signalAll} method for this
-// * <tt>Condition</tt>; or
-// * <li>Some other thread {@link Thread#interrupt interrupts} the current
-// * thread, and interruption of thread suspension is supported; or
-// * <li>The specified waiting time elapses; or
-// * <li>A &quot;<em>spurious wakeup</em>&quot; occurs.
-// * </ul>
-// *
-// * <p>In all cases, before this method can return the current thread must
-// * re-acquire the lock associated with this condition. When the
-// * thread returns it is <em>guaranteed</em> to hold this lock.
-// *
-// * <p>If the current thread:
-// * <ul>
-// * <li>has its interrupted status set on entry to this method; or
-// * <li>is {@link Thread#interrupt interrupted} while waiting
-// * and interruption of thread suspension is supported,
-// * </ul>
-// * then {@link InterruptedException} is thrown and the current thread's
-// * interrupted status is cleared. It is not specified, in the first
-// * case, whether or not the test for interruption occurs before the lock
-// * is released.
-// *
-// * <p>The method returns an estimate of the number of nanoseconds
-// * remaining to wait given the supplied <tt>nanosTimeout</tt>
-// * value upon return, or a value less than or equal to zero if it
-// * timed out. This value can be used to determine whether and how
-// * long to re-wait in cases where the wait returns but an awaited
-// * condition still does not hold. Typical uses of this method take
-// * the following form:
-// *
-// * <pre>
-// * synchronized boolean aMethod(long timeout, TimeUnit unit) {
-// * long nanosTimeout = unit.toNanos(timeout);
-// * while (!conditionBeingWaitedFor) {
-// * if (nanosTimeout &gt; 0)
-// * nanosTimeout = theCondition.awaitNanos(nanosTimeout);
-// * else
-// * return false;
-// * }
-// * // ...
-// * }
-// * </pre>
-// *
-// * <p> Design note: This method requires a nanosecond argument so
-// * as to avoid truncation errors in reporting remaining times.
-// * Such precision loss would make it difficult for programmers to
-// * ensure that total waiting times are not systematically shorter
-// * than specified when re-waits occur.
-// *
-// * <p><b>Implementation Considerations</b>
-// * <p>The current thread is assumed to hold the lock associated with this
-// * <tt>Condition</tt> when this method is called.
-// * It is up to the implementation to determine if this is
-// * the case and if not, how to respond. Typically, an exception will be
-// * thrown (such as {@link IllegalMonitorStateException}) and the
-// * implementation must document that fact.
-// *
-// * <p>An implementation can favor responding to an interrupt over normal
-// * method return in response to a signal, or over indicating the elapse
-// * of the specified waiting time. In either case the implementation
-// * must ensure that the signal is redirected to another waiting thread, if
-// * there is one.
-// *
-// * @param nanosTimeout the maximum time to wait, in nanoseconds
-// * @return A value less than or equal to zero if the wait has
-// * timed out; otherwise an estimate, that
-// * is strictly less than the <tt>nanosTimeout</tt> argument,
-// * of the time still remaining when this method returned.
-// *
-// * @throws InterruptedException if the current thread is interrupted (and
-// * interruption of thread suspension is supported).
-// */
-// long awaitNanos(long nanosTimeout) throws InterruptedException;
-
- /**
- * Causes the current thread to wait until it is signalled or interrupted,
- * or the specified waiting time elapses. This method is behaviorally
- * equivalent to:<br>
- * <pre>
- * awaitNanos(unit.toNanos(time)) &gt; 0
- * </pre>
- * @param time the maximum time to wait
- * @param unit the time unit of the {@code time} argument
- * @return {@code false} if the waiting time detectably elapsed
- * before return from the method, else {@code true}
- * @throws InterruptedException if the current thread is interrupted
- * (and interruption of thread suspension is supported)
- */
- boolean await(long time, TimeUnit unit) throws InterruptedException;
-
- /**
- * Causes the current thread to wait until it is signalled or interrupted,
- * or the specified deadline elapses.
- *
- * <p>The lock associated with this condition is atomically
- * released and the current thread becomes disabled for thread scheduling
- * purposes and lies dormant until <em>one</em> of five things happens:
- * <ul>
- * <li>Some other thread invokes the {@link #signal} method for this
- * {@code Condition} and the current thread happens to be chosen as the
- * thread to be awakened; or
- * <li>Some other thread invokes the {@link #signalAll} method for this
- * {@code Condition}; or
- * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
- * current thread, and interruption of thread suspension is supported; or
- * <li>The specified deadline elapses; or
- * <li>A &quot;<em>spurious wakeup</em>&quot; occurs.
- * </ul>
- *
- * <p>In all cases, before this method can return the current thread must
- * re-acquire the lock associated with this condition. When the
- * thread returns it is <em>guaranteed</em> to hold this lock.
- *
- *
- * <p>If the current thread:
- * <ul>
- * <li>has its interrupted status set on entry to this method; or
- * <li>is {@linkplain Thread#interrupt interrupted} while waiting
- * and interruption of thread suspension is supported,
- * </ul>
- * then {@link InterruptedException} is thrown and the current thread's
- * interrupted status is cleared. It is not specified, in the first
- * case, whether or not the test for interruption occurs before the lock
- * is released.
- *
- *
- * <p>The return value indicates whether the deadline has elapsed,
- * which can be used as follows:
- * <pre>
- * synchronized boolean aMethod(Date deadline) {
- * boolean stillWaiting = true;
- * while (!conditionBeingWaitedFor) {
- * if (stillWaiting)
- * stillWaiting = theCondition.awaitUntil(deadline);
- * else
- * return false;
- * }
- * // ...
- * }
- * </pre>
- *
- * <p><b>Implementation Considerations</b>
- *
- * <p>The current thread is assumed to hold the lock associated with this
- * {@code Condition} when this method is called.
- * It is up to the implementation to determine if this is
- * the case and if not, how to respond. Typically, an exception will be
- * thrown (such as {@link IllegalMonitorStateException}) and the
- * implementation must document that fact.
- *
- * <p>An implementation can favor responding to an interrupt over normal
- * method return in response to a signal, or over indicating the passing
- * of the specified deadline. In either case the implementation
- * must ensure that the signal is redirected to another waiting thread, if
- * there is one.
- *
- * @param deadline the absolute time to wait until
- * @return {@code false} if the deadline has elapsed upon return, else
- * {@code true}
- * @throws InterruptedException if the current thread is interrupted
- * (and interruption of thread suspension is supported)
- */
- boolean awaitUntil(Date deadline) throws InterruptedException;
-
- /**
- * Wakes up one waiting thread.
- *
- * <p>If any threads are waiting on this condition then one
- * is selected for waking up. That thread must then re-acquire the
- * lock before returning from {@code await}.
- */
- void signal();
-
- /**
- * Wakes up all waiting threads.
- *
- * <p>If any threads are waiting on this condition then they are
- * all woken up. Each thread must re-acquire the lock before it can
- * return from {@code await}.
- */
- void signalAll();
-}
diff --git a/src/actors/scala/actors/threadpool/locks/FIFOCondVar.java b/src/actors/scala/actors/threadpool/locks/FIFOCondVar.java
deleted file mode 100644
index 144ac54d37..0000000000
--- a/src/actors/scala/actors/threadpool/locks/FIFOCondVar.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- File: ConditionVariable.java
- Originally written by Doug Lea and released into the public domain.
- This may be used for any purposes whatsoever without acknowledgment.
- Thanks for the assistance and support of Sun Microsystems Labs,
- and everyone contributing, testing, and using this code.
- History:
- Date Who What
- 11Jun1998 dl Create public version
- */
-
-package scala.actors.threadpool.locks;
-
-import java.util.Collection;
-import java.util.Date;
-import scala.actors.threadpool.*;
-import scala.actors.threadpool.helpers.*;
-
-class FIFOCondVar extends CondVar implements Condition, java.io.Serializable {
- private static final long serialVersionUID = -497497271881010475L;
-
- private static final WaitQueue.QueuedSync sync = new WaitQueue.QueuedSync() {
- public boolean recheck(WaitQueue.WaitNode node) { return false; }
- public void takeOver(WaitQueue.WaitNode node) {}
- };
-
- // wait queue; only accessed when holding the lock
- private final WaitQueue wq = new FIFOWaitQueue();
-
- /**
- * Create a new CondVar that relies on the given mutual exclusion lock.
- * @param lock A non-reentrant mutual exclusion lock.
- */
- FIFOCondVar(ExclusiveLock lock) {
- super(lock);
- }
-
- public void awaitUninterruptibly() {
- int holdCount = lock.getHoldCount();
- if (holdCount == 0) {
- throw new IllegalMonitorStateException();
- }
- WaitQueue.WaitNode n = new WaitQueue.WaitNode();
- wq.insert(n);
- for (int i=holdCount; i>0; i--) lock.unlock();
- try {
- n.doWaitUninterruptibly(sync);
- }
- finally {
- for (int i=holdCount; i>0; i--) lock.lock();
- }
- }
-
- public void await() throws InterruptedException {
- int holdCount = lock.getHoldCount();
- if (holdCount == 0) {
- throw new IllegalMonitorStateException();
- }
- if (Thread.interrupted()) throw new InterruptedException();
- WaitQueue.WaitNode n = new WaitQueue.WaitNode();
- wq.insert(n);
- for (int i=holdCount; i>0; i--) lock.unlock();
- try {
- n.doWait(sync);
- }
- finally {
- for (int i=holdCount; i>0; i--) lock.lock();
- }
- }
-
- public boolean await(long timeout, TimeUnit unit) throws InterruptedException {
- int holdCount = lock.getHoldCount();
- if (holdCount == 0) {
- throw new IllegalMonitorStateException();
- }
- if (Thread.interrupted()) throw new InterruptedException();
- long nanos = unit.toNanos(timeout);
- WaitQueue.WaitNode n = new WaitQueue.WaitNode();
- wq.insert(n);
- boolean success = false;
- for (int i=holdCount; i>0; i--) lock.unlock();
- try {
- success = n.doTimedWait(sync, nanos);
- }
- finally {
- for (int i=holdCount; i>0; i--) lock.lock();
- }
- return success;
- }
-
-// public long awaitNanos(long timeout) throws InterruptedException {
-// throw new UnsupportedOperationException();
-// }
-//
- public boolean awaitUntil(Date deadline) throws InterruptedException {
- if (deadline == null) throw new NullPointerException();
- long abstime = deadline.getTime();
- long start = System.currentTimeMillis();
- long msecs = abstime - start;
- return await(msecs, TimeUnit.MILLISECONDS);
- }
-
- public void signal() {
- if (!lock.isHeldByCurrentThread()) {
- throw new IllegalMonitorStateException();
- }
- for (;;) {
- WaitQueue.WaitNode w = wq.extract();
- if (w == null) return; // no one to signal
- if (w.signal(sync)) return; // notify if still waiting, else skip
- }
- }
-
- public void signalAll() {
- if (!lock.isHeldByCurrentThread()) {
- throw new IllegalMonitorStateException();
- }
- for (;;) {
- WaitQueue.WaitNode w = wq.extract();
- if (w == null) return; // no more to signal
- w.signal(sync);
- }
- }
-
- protected boolean hasWaiters() {
- if (!lock.isHeldByCurrentThread()) {
- throw new IllegalMonitorStateException();
- }
- return wq.hasNodes();
- }
-
- protected int getWaitQueueLength() {
- if (!lock.isHeldByCurrentThread()) {
- throw new IllegalMonitorStateException();
- }
- return wq.getLength();
- }
-
- protected Collection getWaitingThreads() {
- if (!lock.isHeldByCurrentThread()) {
- throw new IllegalMonitorStateException();
- }
- return wq.getWaitingThreads();
- }
-
-
-}
diff --git a/src/actors/scala/actors/threadpool/locks/Lock.java b/src/actors/scala/actors/threadpool/locks/Lock.java
deleted file mode 100644
index 47a4e8e777..0000000000
--- a/src/actors/scala/actors/threadpool/locks/Lock.java
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
- */
-
-package scala.actors.threadpool.locks;
-
-import scala.actors.threadpool.TimeUnit;
-
-/**
- * {@code Lock} implementations provide more extensive locking
- * operations than can be obtained using {@code synchronized} methods
- * and statements. They allow more flexible structuring, may have
- * quite different properties, and may support multiple associated
- * {@link Condition} objects.
- *
- * <p>A lock is a tool for controlling access to a shared resource by
- * multiple threads. Commonly, a lock provides exclusive access to a
- * shared resource: only one thread at a time can acquire the lock and
- * all access to the shared resource requires that the lock be
- * acquired first. However, some locks may allow concurrent access to
- * a shared resource, such as the read lock of a {@link ReadWriteLock}.
- *
- * <p>The use of {@code synchronized} methods or statements provides
- * access to the implicit monitor lock associated with every object, but
- * forces all lock acquisition and release to occur in a block-structured way:
- * when multiple locks are acquired they must be released in the opposite
- * order, and all locks must be released in the same lexical scope in which
- * they were acquired.
- *
- * <p>While the scoping mechanism for {@code synchronized} methods
- * and statements makes it much easier to program with monitor locks,
- * and helps avoid many common programming errors involving locks,
- * there are occasions where you need to work with locks in a more
- * flexible way. For example, some algorithms for traversing
- * concurrently accessed data structures require the use of
- * &quot;hand-over-hand&quot; or &quot;chain locking&quot;: you
- * acquire the lock of node A, then node B, then release A and acquire
- * C, then release B and acquire D and so on. Implementations of the
- * {@code Lock} interface enable the use of such techniques by
- * allowing a lock to be acquired and released in different scopes,
- * and allowing multiple locks to be acquired and released in any
- * order.
- *
- * <p>With this increased flexibility comes additional
- * responsibility. The absence of block-structured locking removes the
- * automatic release of locks that occurs with {@code synchronized}
- * methods and statements. In most cases, the following idiom
- * should be used:
- *
- * <pre><tt> Lock l = ...;
- * l.lock();
- * try {
- * // access the resource protected by this lock
- * } finally {
- * l.unlock();
- * }
- * </tt></pre>
- *
- * When locking and unlocking occur in different scopes, care must be
- * taken to ensure that all code that is executed while the lock is
- * held is protected by try-finally or try-catch to ensure that the
- * lock is released when necessary.
- *
- * <p>{@code Lock} implementations provide additional functionality
- * over the use of {@code synchronized} methods and statements by
- * providing a non-blocking attempt to acquire a lock ({@link
- * #tryLock()}), an attempt to acquire the lock that can be
- * interrupted ({@link #lockInterruptibly}, and an attempt to acquire
- * the lock that can timeout ({@link #tryLock(long, TimeUnit)}).
- *
- * <p>A {@code Lock} class can also provide behavior and semantics
- * that is quite different from that of the implicit monitor lock,
- * such as guaranteed ordering, non-reentrant usage, or deadlock
- * detection. If an implementation provides such specialized semantics
- * then the implementation must document those semantics.
- *
- * <p>Note that {@code Lock} instances are just normal objects and can
- * themselves be used as the target in a {@code synchronized} statement.
- * Acquiring the
- * monitor lock of a {@code Lock} instance has no specified relationship
- * with invoking any of the {@link #lock} methods of that instance.
- * It is recommended that to avoid confusion you never use {@code Lock}
- * instances in this way, except within their own implementation.
- *
- * <p>Except where noted, passing a {@code null} value for any
- * parameter will result in a {@link NullPointerException} being
- * thrown.
- *
- * <h3>Memory Synchronization</h3>
- *
- * <p>All {@code Lock} implementations <em>must</em> enforce the same
- * memory synchronization semantics as provided by the built-in monitor
- * lock, as described in <a href="http://java.sun.com/docs/books/jls/">
- * The Java Language Specification, Third Edition (17.4 Memory Model)</a>:
- * <ul>
- * <li>A successful {@code lock} operation has the same memory
- * synchronization effects as a successful <em>Lock</em> action.
- * <li>A successful {@code unlock} operation has the same
- * memory synchronization effects as a successful <em>Unlock</em> action.
- * </ul>
- *
- * Unsuccessful locking and unlocking operations, and reentrant
- * locking/unlocking operations, do not require any memory
- * synchronization effects.
- *
- * <h3>Implementation Considerations</h3>
- *
- * <p> The three forms of lock acquisition (interruptible,
- * non-interruptible, and timed) may differ in their performance
- * characteristics, ordering guarantees, or other implementation
- * qualities. Further, the ability to interrupt the <em>ongoing</em>
- * acquisition of a lock may not be available in a given {@code Lock}
- * class. Consequently, an implementation is not required to define
- * exactly the same guarantees or semantics for all three forms of
- * lock acquisition, nor is it required to support interruption of an
- * ongoing lock acquisition. An implementation is required to clearly
- * document the semantics and guarantees provided by each of the
- * locking methods. It must also obey the interruption semantics as
- * defined in this interface, to the extent that interruption of lock
- * acquisition is supported: which is either totally, or only on
- * method entry.
- *
- * <p>As interruption generally implies cancellation, and checks for
- * interruption are often infrequent, an implementation can favor responding
- * to an interrupt over normal method return. This is true even if it can be
- * shown that the interrupt occurred after another action may have unblocked
- * the thread. An implementation should document this behavior.
- *
- * @see ReentrantLock
- * @see Condition
- * @see ReadWriteLock
- *
- * @since 1.5
- * @author Doug Lea
- */
-public interface Lock {
-
- /**
- * Acquires the lock.
- *
- * <p>If the lock is not available then the current thread becomes
- * disabled for thread scheduling purposes and lies dormant until the
- * lock has been acquired.
- *
- * <p><b>Implementation Considerations</b>
- *
- * <p>A {@code Lock} implementation may be able to detect erroneous use
- * of the lock, such as an invocation that would cause deadlock, and
- * may throw an (unchecked) exception in such circumstances. The
- * circumstances and the exception type must be documented by that
- * {@code Lock} implementation.
- */
- void lock();
-
- /**
- * Acquires the lock unless the current thread is
- * {@linkplain Thread#interrupt interrupted}.
- *
- * <p>Acquires the lock if it is available and returns immediately.
- *
- * <p>If the lock is not available then the current thread becomes
- * disabled for thread scheduling purposes and lies dormant until
- * one of two things happens:
- *
- * <ul>
- * <li>The lock is acquired by the current thread; or
- * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
- * current thread, and interruption of lock acquisition is supported.
- * </ul>
- *
- * <p>If the current thread:
- * <ul>
- * <li>has its interrupted status set on entry to this method; or
- * <li>is {@linkplain Thread#interrupt interrupted} while acquiring the
- * lock, and interruption of lock acquisition is supported,
- * </ul>
- * then {@link InterruptedException} is thrown and the current thread's
- * interrupted status is cleared.
- *
- * <p><b>Implementation Considerations</b>
- *
- * <p>The ability to interrupt a lock acquisition in some
- * implementations may not be possible, and if possible may be an
- * expensive operation. The programmer should be aware that this
- * may be the case. An implementation should document when this is
- * the case.
- *
- * <p>An implementation can favor responding to an interrupt over
- * normal method return.
- *
- * <p>A {@code Lock} implementation may be able to detect
- * erroneous use of the lock, such as an invocation that would
- * cause deadlock, and may throw an (unchecked) exception in such
- * circumstances. The circumstances and the exception type must
- * be documented by that {@code Lock} implementation.
- *
- * @throws InterruptedException if the current thread is
- * interrupted while acquiring the lock (and interruption
- * of lock acquisition is supported).
- */
- void lockInterruptibly() throws InterruptedException;
-
- /**
- * Acquires the lock only if it is free at the time of invocation.
- *
- * <p>Acquires the lock if it is available and returns immediately
- * with the value {@code true}.
- * If the lock is not available then this method will return
- * immediately with the value {@code false}.
- *
- * <p>A typical usage idiom for this method would be:
- * <pre>
- * Lock lock = ...;
- * if (lock.tryLock()) {
- * try {
- * // manipulate protected state
- * } finally {
- * lock.unlock();
- * }
- * } else {
- * // perform alternative actions
- * }
- * </pre>
- * This usage ensures that the lock is unlocked if it was acquired, and
- * doesn't try to unlock if the lock was not acquired.
- *
- * @return {@code true} if the lock was acquired and
- * {@code false} otherwise
- */
- boolean tryLock();
-
- /**
- * Acquires the lock if it is free within the given waiting time and the
- * current thread has not been {@linkplain Thread#interrupt interrupted}.
- *
- * <p>If the lock is available this method returns immediately
- * with the value {@code true}.
- * If the lock is not available then
- * the current thread becomes disabled for thread scheduling
- * purposes and lies dormant until one of three things happens:
- * <ul>
- * <li>The lock is acquired by the current thread; or
- * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
- * current thread, and interruption of lock acquisition is supported; or
- * <li>The specified waiting time elapses
- * </ul>
- *
- * <p>If the lock is acquired then the value {@code true} is returned.
- *
- * <p>If the current thread:
- * <ul>
- * <li>has its interrupted status set on entry to this method; or
- * <li>is {@linkplain Thread#interrupt interrupted} while acquiring
- * the lock, and interruption of lock acquisition is supported,
- * </ul>
- * then {@link InterruptedException} is thrown and the current thread's
- * interrupted status is cleared.
- *
- * <p>If the specified waiting time elapses then the value {@code false}
- * is returned.
- * If the time is
- * less than or equal to zero, the method will not wait at all.
- *
- * <p><b>Implementation Considerations</b>
- *
- * <p>The ability to interrupt a lock acquisition in some implementations
- * may not be possible, and if possible may
- * be an expensive operation.
- * The programmer should be aware that this may be the case. An
- * implementation should document when this is the case.
- *
- * <p>An implementation can favor responding to an interrupt over normal
- * method return, or reporting a timeout.
- *
- * <p>A {@code Lock} implementation may be able to detect
- * erroneous use of the lock, such as an invocation that would cause
- * deadlock, and may throw an (unchecked) exception in such circumstances.
- * The circumstances and the exception type must be documented by that
- * {@code Lock} implementation.
- *
- * @param time the maximum time to wait for the lock
- * @param unit the time unit of the {@code time} argument
- * @return {@code true} if the lock was acquired and {@code false}
- * if the waiting time elapsed before the lock was acquired
- *
- * @throws InterruptedException if the current thread is interrupted
- * while acquiring the lock (and interruption of lock
- * acquisition is supported)
- */
- boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
-
- /**
- * Releases the lock.
- *
- * <p><b>Implementation Considerations</b>
- *
- * <p>A {@code Lock} implementation will usually impose
- * restrictions on which thread can release a lock (typically only the
- * holder of the lock can release it) and may throw
- * an (unchecked) exception if the restriction is violated.
- * Any restrictions and the exception
- * type must be documented by that {@code Lock} implementation.
- */
- void unlock();
-
- /**
- * Returns a new {@link Condition} instance that is bound to this
- * {@code Lock} instance.
- *
- * <p>Before waiting on the condition the lock must be held by the
- * current thread.
- * A call to {@link Condition#await()} will atomically release the lock
- * before waiting and re-acquire the lock before the wait returns.
- *
- * <p><b>Implementation Considerations</b>
- *
- * <p>The exact operation of the {@link Condition} instance depends on
- * the {@code Lock} implementation and must be documented by that
- * implementation.
- *
- * @return A new {@link Condition} instance for this {@code Lock} instance
- * @throws UnsupportedOperationException if this {@code Lock}
- * implementation does not support conditions
- */
- Condition newCondition();
-}
diff --git a/src/actors/scala/actors/threadpool/locks/ReadWriteLock.java b/src/actors/scala/actors/threadpool/locks/ReadWriteLock.java
deleted file mode 100644
index 02983f9bd4..0000000000
--- a/src/actors/scala/actors/threadpool/locks/ReadWriteLock.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
- */
-
-package scala.actors.threadpool.locks;
-
-/**
- * A <tt>ReadWriteLock</tt> maintains a pair of associated {@link
- * Lock locks}, one for read-only operations and one for writing.
- * The {@link #readLock read lock} may be held simultaneously by
- * multiple reader threads, so long as there are no writers. The
- * {@link #writeLock write lock} is exclusive.
- *
- * <p>All <tt>ReadWriteLock</tt> implementations must guarantee that
- * the memory synchronization effects of <tt>writeLock</tt> operations
- * (as specified in the {@link Lock} interface) also hold with respect
- * to the associated <tt>readLock</tt>. That is, a thread successfully
- * acquiring the read lock will see all updates made upon previous
- * release of the write lock.
- *
- * <p>A read-write lock allows for a greater level of concurrency in
- * accessing shared data than that permitted by a mutual exclusion lock.
- * It exploits the fact that while only a single thread at a time (a
- * <em>writer</em> thread) can modify the shared data, in many cases any
- * number of threads can concurrently read the data (hence <em>reader</em>
- * threads).
- * In theory, the increase in concurrency permitted by the use of a read-write
- * lock will lead to performance improvements over the use of a mutual
- * exclusion lock. In practice this increase in concurrency will only be fully
- * realized on a multi-processor, and then only if the access patterns for
- * the shared data are suitable.
- *
- * <p>Whether or not a read-write lock will improve performance over the use
- * of a mutual exclusion lock depends on the frequency that the data is
- * read compared to being modified, the duration of the read and write
- * operations, and the contention for the data - that is, the number of
- * threads that will try to read or write the data at the same time.
- * For example, a collection that is initially populated with data and
- * thereafter infrequently modified, while being frequently searched
- * (such as a directory of some kind) is an ideal candidate for the use of
- * a read-write lock. However, if updates become frequent then the data
- * spends most of its time being exclusively locked and there is little, if any
- * increase in concurrency. Further, if the read operations are too short
- * the overhead of the read-write lock implementation (which is inherently
- * more complex than a mutual exclusion lock) can dominate the execution
- * cost, particularly as many read-write lock implementations still serialize
- * all threads through a small section of code. Ultimately, only profiling
- * and measurement will establish whether the use of a read-write lock is
- * suitable for your application.
- *
- *
- * <p>Although the basic operation of a read-write lock is straight-forward,
- * there are many policy decisions that an implementation must make, which
- * may affect the effectiveness of the read-write lock in a given application.
- * Examples of these policies include:
- * <ul>
- * <li>Determining whether to grant the read lock or the write lock, when
- * both readers and writers are waiting, at the time that a writer releases
- * the write lock. Writer preference is common, as writes are expected to be
- * short and infrequent. Reader preference is less common as it can lead to
- * lengthy delays for a write if the readers are frequent and long-lived as
- * expected. Fair, or &quot;in-order&quot; implementations are also possible.
- *
- * <li>Determining whether readers that request the read lock while a
- * reader is active and a writer is waiting, are granted the read lock.
- * Preference to the reader can delay the writer indefinitely, while
- * preference to the writer can reduce the potential for concurrency.
- *
- * <li>Determining whether the locks are reentrant: can a thread with the
- * write lock reacquire it? Can it acquire a read lock while holding the
- * write lock? Is the read lock itself reentrant?
- *
- * <li>Can the write lock be downgraded to a read lock without allowing
- * an intervening writer? Can a read lock be upgraded to a write lock,
- * in preference to other waiting readers or writers?
- *
- * </ul>
- * You should consider all of these things when evaluating the suitability
- * of a given implementation for your application.
- *
- * @see ReentrantReadWriteLock
- * @see Lock
- * @see ReentrantLock
- *
- * @since 1.5
- * @author Doug Lea
- */
-public interface ReadWriteLock {
- /**
- * Returns the lock used for reading.
- *
- * @return the lock used for reading.
- */
- Lock readLock();
-
- /**
- * Returns the lock used for writing.
- *
- * @return the lock used for writing.
- */
- Lock writeLock();
-}
diff --git a/src/actors/scala/actors/threadpool/locks/ReentrantLock.java b/src/actors/scala/actors/threadpool/locks/ReentrantLock.java
deleted file mode 100644
index b42ddd611b..0000000000
--- a/src/actors/scala/actors/threadpool/locks/ReentrantLock.java
+++ /dev/null
@@ -1,959 +0,0 @@
-/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
- */
-
-package scala.actors.threadpool.locks;
-
-import java.util.Collection;
-import scala.actors.threadpool.*;
-import scala.actors.threadpool.helpers.*;
-
-/**
- * A reentrant mutual exclusion {@link Lock} with the same basic
- * behavior and semantics as the implicit monitor lock accessed using
- * {@code synchronized} methods and statements, but with extended
- * capabilities.
- *
- * <p>A {@code ReentrantLock} is <em>owned</em> by the thread last
- * successfully locking, but not yet unlocking it. A thread invoking
- * {@code lock} will return, successfully acquiring the lock, when
- * the lock is not owned by another thread. The method will return
- * immediately if the current thread already owns the lock. This can
- * be checked using methods {@link #isHeldByCurrentThread}, and {@link
- * #getHoldCount}.
- *
- * <p>The constructor for this class accepts an optional
- * <em>fairness</em> parameter. When set {@code true}, under
- * contention, locks favor granting access to the longest-waiting
- * thread. Otherwise this lock does not guarantee any particular
- * access order. Programs using fair locks accessed by many threads
- * may display lower overall throughput (i.e., are slower; often much
- * slower) than those using the default setting, but have smaller
- * variances in times to obtain locks and guarantee lack of
- * starvation. Note however, that fairness of locks does not guarantee
- * fairness of thread scheduling. Thus, one of many threads using a
- * fair lock may obtain it multiple times in succession while other
- * active threads are not progressing and not currently holding the
- * lock.
- * Also note that the untimed {@link #tryLock() tryLock} method does not
- * honor the fairness setting. It will succeed if the lock
- * is available even if other threads are waiting.
- *
- * <p>It is recommended practice to <em>always</em> immediately
- * follow a call to {@code lock} with a {@code try} block, most
- * typically in a before/after construction such as:
- *
- * <pre>
- * class X {
- * private final ReentrantLock lock = new ReentrantLock();
- * // ...
- *
- * public void m() {
- * lock.lock(); // block until condition holds
- * try {
- * // ... method body
- * } finally {
- * lock.unlock()
- * }
- * }
- * }
- * </pre>
- *
- * <p>In addition to implementing the {@link Lock} interface, this
- * class defines methods {@code isLocked} and
- * {@code getLockQueueLength}, as well as some associated
- * {@code protected} access methods that may be useful for
- * instrumentation and monitoring.
- *
- * <p>Serialization of this class behaves in the same way as built-in
- * locks: a deserialized lock is in the unlocked state, regardless of
- * its state when serialized.
- *
- * <p>This lock supports a maximum of 2147483647 recursive locks by
- * the same thread. Attempts to exceed this limit result in
- * {@link Error} throws from locking methods.
- *
- * @since 1.5
- * @author Doug Lea
- * @author Dawid Kurzyniec
- */
-public class ReentrantLock implements Lock, java.io.Serializable,
- CondVar.ExclusiveLock {
- private static final long serialVersionUID = 7373984872572414699L;
-
- private final Sync sync;
-
- /**
- * Base of synchronization control for this lock. Subclassed
- * into fair and nonfair versions below.
- */
- static abstract class Sync implements java.io.Serializable {
- private static final long serialVersionUID = -5179523762034025860L;
-
- protected transient Thread owner_ = null;
- protected transient int holds_ = 0;
-
- protected Sync() {}
-
- /**
- * Performs {@link Lock#lock}. The main reason for subclassing
- * is to allow fast path for nonfair version.
- */
- public abstract void lock();
-
- public abstract void lockInterruptibly() throws InterruptedException;
-
- final void incHolds() {
- int nextHolds = ++holds_;
- if (nextHolds < 0)
- throw new Error("Maximum lock count exceeded");
- holds_ = nextHolds;
- }
-
- public boolean tryLock() {
- Thread caller = Thread.currentThread();
- synchronized (this) {
- if (owner_ == null) {
- owner_ = caller;
- holds_ = 1;
- return true;
- }
- else if (caller == owner_) {
- incHolds();
- return true;
- }
- }
- return false;
- }
-
- public abstract boolean tryLock(long nanos) throws InterruptedException;
-
- public abstract void unlock();
-
- public synchronized int getHoldCount() {
- return isHeldByCurrentThread() ? holds_ : 0;
- }
-
- public synchronized boolean isHeldByCurrentThread() {
- return holds_ > 0 && Thread.currentThread() == owner_;
- }
-
- public synchronized boolean isLocked() {
- return owner_ != null;
- }
-
- public abstract boolean isFair();
-
- protected synchronized Thread getOwner() {
- return owner_;
- }
-
- public boolean hasQueuedThreads() {
- throw new UnsupportedOperationException("Use FAIR version");
- }
-
- public int getQueueLength() {
- throw new UnsupportedOperationException("Use FAIR version");
- }
-
- public Collection getQueuedThreads() {
- throw new UnsupportedOperationException("Use FAIR version");
- }
-
- public boolean isQueued(Thread thread) {
- throw new UnsupportedOperationException("Use FAIR version");
- }
- }
-
- /**
- * Sync object for non-fair locks
- */
- final static class NonfairSync extends Sync {
- private static final long serialVersionUID = 7316153563782823691L;
-
- NonfairSync() {}
-
- /**
- * Performs lock. Try immediate barge, backing up to normal
- * acquire on failure.
- */
- public void lock() {
- Thread caller = Thread.currentThread();
- synchronized (this) {
- if (owner_ == null) {
- owner_ = caller;
- holds_ = 1;
- return;
- }
- else if (caller == owner_) {
- incHolds();
- return;
- }
- else {
- boolean wasInterrupted = Thread.interrupted();
- try {
- while (true) {
- try {
- wait();
- }
- catch (InterruptedException e) {
- wasInterrupted = true;
- // no need to notify; if we were signalled, we
- // will act as signalled, ignoring the
- // interruption
- }
- if (owner_ == null) {
- owner_ = caller;
- holds_ = 1;
- return;
- }
- }
- }
- finally {
- if (wasInterrupted) Thread.currentThread().interrupt();
- }
- }
- }
- }
-
- public void lockInterruptibly() throws InterruptedException {
- if (Thread.interrupted()) throw new InterruptedException();
- Thread caller = Thread.currentThread();
- synchronized (this) {
- if (owner_ == null) {
- owner_ = caller;
- holds_ = 1;
- return;
- }
- else if (caller == owner_) {
- incHolds();
- return;
- }
- else {
- try {
- do { wait(); } while (owner_ != null);
- owner_ = caller;
- holds_ = 1;
- return;
- }
- catch (InterruptedException ex) {
- if (owner_ == null) notify();
- throw ex;
- }
- }
- }
- }
-
- public boolean tryLock(long nanos) throws InterruptedException {
- if (Thread.interrupted()) throw new InterruptedException();
- Thread caller = Thread.currentThread();
-
- synchronized (this) {
- if (owner_ == null) {
- owner_ = caller;
- holds_ = 1;
- return true;
- }
- else if (caller == owner_) {
- incHolds();
- return true;
- }
- else if (nanos <= 0)
- return false;
- else {
- long deadline = Utils.nanoTime() + nanos;
- try {
- for (; ; ) {
- TimeUnit.NANOSECONDS.timedWait(this, nanos);
- if (caller == owner_) {
- incHolds();
- return true;
- }
- else if (owner_ == null) {
- owner_ = caller;
- holds_ = 1;
- return true;
- }
- else {
- nanos = deadline - Utils.nanoTime();
- if (nanos <= 0)
- return false;
- }
- }
- }
- catch (InterruptedException ex) {
- if (owner_ == null) notify();
- throw ex;
- }
- }
- }
- }
-
- public synchronized void unlock() {
- if (Thread.currentThread() != owner_)
- throw new IllegalMonitorStateException("Not owner");
-
- if (--holds_ == 0) {
- owner_ = null;
- notify();
- }
- }
-
- public final boolean isFair() {
- return false;
- }
- }
-
- /**
- * Sync object for fair locks
- */
- final static class FairSync extends Sync implements WaitQueue.QueuedSync {
- private static final long serialVersionUID = -3000897897090466540L;
-
- private transient WaitQueue wq_ = new FIFOWaitQueue();
-
- FairSync() {}
-
- public synchronized boolean recheck(WaitQueue.WaitNode node) {
- Thread caller = Thread.currentThread();
- if (owner_ == null) {
- owner_ = caller;
- holds_ = 1;
- return true;
- }
- else if (caller == owner_) {
- incHolds();
- return true;
- }
- wq_.insert(node);
- return false;
- }
-
- public synchronized void takeOver(WaitQueue.WaitNode node) {
- // assert (holds_ == 1 && owner_ == Thread.currentThread()
- owner_ = node.getOwner();
- }
-
- public void lock() {
- Thread caller = Thread.currentThread();
- synchronized (this) {
- if (owner_ == null) {
- owner_ = caller;
- holds_ = 1;
- return;
- }
- else if (caller == owner_) {
- incHolds();
- return;
- }
- }
- WaitQueue.WaitNode n = new WaitQueue.WaitNode();
- n.doWaitUninterruptibly(this);
- }
-
- public void lockInterruptibly() throws InterruptedException {
- if (Thread.interrupted()) throw new InterruptedException();
- Thread caller = Thread.currentThread();
- synchronized (this) {
- if (owner_ == null) {
- owner_ = caller;
- holds_ = 1;
- return;
- }
- else if (caller == owner_) {
- incHolds();
- return;
- }
- }
- WaitQueue.WaitNode n = new WaitQueue.WaitNode();
- n.doWait(this);
- }
-
- public boolean tryLock(long nanos) throws InterruptedException {
- if (Thread.interrupted()) throw new InterruptedException();
- Thread caller = Thread.currentThread();
- synchronized (this) {
- if (owner_ == null) {
- owner_ = caller;
- holds_ = 1;
- return true;
- }
- else if (caller == owner_) {
- incHolds();
- return true;
- }
- }
- WaitQueue.WaitNode n = new WaitQueue.WaitNode();
- return n.doTimedWait(this, nanos);
- }
-
- protected synchronized WaitQueue.WaitNode getSignallee(Thread caller) {
- if (caller != owner_)
- throw new IllegalMonitorStateException("Not owner");
- // assert (holds_ > 0)
- if (holds_ >= 2) { // current thread will keep the lock
- --holds_;
- return null;
- }
- // assert (holds_ == 1)
- WaitQueue.WaitNode w = wq_.extract();
- if (w == null) { // if none, clear for new arrivals
- owner_ = null;
- holds_ = 0;
- }
- return w;
- }
-
- public void unlock() {
- Thread caller = Thread.currentThread();
- for (;;) {
- WaitQueue.WaitNode w = getSignallee(caller);
- if (w == null) return; // no one to signal
- if (w.signal(this)) return; // notify if still waiting, else skip
- }
- }
-
- public final boolean isFair() {
- return true;
- }
-
- public synchronized boolean hasQueuedThreads() {
- return wq_.hasNodes();
- }
-
- public synchronized int getQueueLength() {
- return wq_.getLength();
- }
-
- public synchronized Collection getQueuedThreads() {
- return wq_.getWaitingThreads();
- }
-
- public synchronized boolean isQueued(Thread thread) {
- return wq_.isWaiting(thread);
- }
-
- private void readObject(java.io.ObjectInputStream in)
- throws java.io.IOException, ClassNotFoundException {
- in.defaultReadObject();
- synchronized (this) {
- wq_ = new FIFOWaitQueue();
- }
- }
- }
-
- /**
- * Creates an instance of {@code ReentrantLock}.
- * This is equivalent to using {@code ReentrantLock(false)}.
- */
- public ReentrantLock() {
- sync = new NonfairSync();
- }
-
- /**
- * Creates an instance of {@code ReentrantLock} with the
- * given fairness policy.
- *
- * @param fair {@code true} if this lock should use a fair ordering policy
- */
- public ReentrantLock(boolean fair) {
- sync = (fair)? (Sync)new FairSync() : new NonfairSync();
- }
-
-
- /**
- * Acquires the lock.
- *
- * <p>Acquires the lock if it is not held by another thread and returns
- * immediately, setting the lock hold count to one.
- *
- * <p>If the current thread already holds the lock then the hold
- * count is incremented by one and the method returns immediately.
- *
- * <p>If the lock is held by another thread then the
- * current thread becomes disabled for thread scheduling
- * purposes and lies dormant until the lock has been acquired,
- * at which time the lock hold count is set to one.
- */
- public void lock() {
- sync.lock();
- }
-
- /**
- * Acquires the lock unless the current thread is
- * {@linkplain Thread#interrupt interrupted}.
- *
- * <p>Acquires the lock if it is not held by another thread and returns
- * immediately, setting the lock hold count to one.
- *
- * <p>If the current thread already holds this lock then the hold count
- * is incremented by one and the method returns immediately.
- *
- * <p>If the lock is held by another thread then the
- * current thread becomes disabled for thread scheduling
- * purposes and lies dormant until one of two things happens:
- *
- * <ul>
- *
- * <li>The lock is acquired by the current thread; or
- *
- * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
- * current thread.
- *
- * </ul>
- *
- * <p>If the lock is acquired by the current thread then the lock hold
- * count is set to one.
- *
- * <p>If the current thread:
- *
- * <ul>
- *
- * <li>has its interrupted status set on entry to this method; or
- *
- * <li>is {@linkplain Thread#interrupt interrupted} while acquiring
- * the lock,
- *
- * </ul>
- *
- * then {@link InterruptedException} is thrown and the current thread's
- * interrupted status is cleared.
- *
- * <p>In this implementation, as this method is an explicit
- * interruption point, preference is given to responding to the
- * interrupt over normal or reentrant acquisition of the lock.
- *
- * @throws InterruptedException if the current thread is interrupted
- */
- public void lockInterruptibly() throws InterruptedException {
- sync.lockInterruptibly();
- }
-
- /**
- * Acquires the lock only if it is not held by another thread at the time
- * of invocation.
- *
- * <p>Acquires the lock if it is not held by another thread and
- * returns immediately with the value {@code true}, setting the
- * lock hold count to one. Even when this lock has been set to use a
- * fair ordering policy, a call to {@code tryLock()} <em>will</em>
- * immediately acquire the lock if it is available, whether or not
- * other threads are currently waiting for the lock.
- * This &quot;barging&quot; behavior can be useful in certain
- * circumstances, even though it breaks fairness. If you want to honor
- * the fairness setting for this lock, then use
- * {@link #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }
- * which is almost equivalent (it also detects interruption).
- *
- * <p> If the current thread already holds this lock then the hold
- * count is incremented by one and the method returns {@code true}.
- *
- * <p>If the lock is held by another thread then this method will return
- * immediately with the value {@code false}.
- *
- * @return {@code true} if the lock was free and was acquired by the
- * current thread, or the lock was already held by the current
- * thread; and {@code false} otherwise
- */
- public boolean tryLock() {
- return sync.tryLock();
- }
-
- /**
- * Acquires the lock if it is not held by another thread within the given
- * waiting time and the current thread has not been
- * {@linkplain Thread#interrupt interrupted}.
- *
- * <p>Acquires the lock if it is not held by another thread and returns
- * immediately with the value {@code true}, setting the lock hold count
- * to one. If this lock has been set to use a fair ordering policy then
- * an available lock <em>will not</em> be acquired if any other threads
- * are waiting for the lock. This is in contrast to the {@link #tryLock()}
- * method. If you want a timed {@code tryLock} that does permit barging on
- * a fair lock then combine the timed and un-timed forms together:
- *
- * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
- * </pre>
- *
- * <p>If the current thread
- * already holds this lock then the hold count is incremented by one and
- * the method returns {@code true}.
- *
- * <p>If the lock is held by another thread then the
- * current thread becomes disabled for thread scheduling
- * purposes and lies dormant until one of three things happens:
- *
- * <ul>
- *
- * <li>The lock is acquired by the current thread; or
- *
- * <li>Some other thread {@linkplain Thread#interrupt interrupts}
- * the current thread; or
- *
- * <li>The specified waiting time elapses
- *
- * </ul>
- *
- * <p>If the lock is acquired then the value {@code true} is returned and
- * the lock hold count is set to one.
- *
- * <p>If the current thread:
- *
- * <ul>
- *
- * <li>has its interrupted status set on entry to this method; or
- *
- * <li>is {@linkplain Thread#interrupt interrupted} while
- * acquiring the lock,
- *
- * </ul>
- * then {@link InterruptedException} is thrown and the current thread's
- * interrupted status is cleared.
- *
- * <p>If the specified waiting time elapses then the value {@code false}
- * is returned. If the time is less than or equal to zero, the method
- * will not wait at all.
- *
- * <p>In this implementation, as this method is an explicit
- * interruption point, preference is given to responding to the
- * interrupt over normal or reentrant acquisition of the lock, and
- * over reporting the elapse of the waiting time.
- *
- * @param timeout the time to wait for the lock
- * @param unit the time unit of the timeout argument
- * @return {@code true} if the lock was free and was acquired by the
- * current thread, or the lock was already held by the current
- * thread; and {@code false} if the waiting time elapsed before
- * the lock could be acquired
- * @throws InterruptedException if the current thread is interrupted
- * @throws NullPointerException if the time unit is null
- *
- */
- public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
- return sync.tryLock(unit.toNanos(timeout));
- }
-
- /**
- * Attempts to release this lock.
- *
- * <p>If the current thread is the holder of this lock then the hold
- * count is decremented. If the hold count is now zero then the lock
- * is released. If the current thread is not the holder of this
- * lock then {@link IllegalMonitorStateException} is thrown.
- *
- * @throws IllegalMonitorStateException if the current thread does not
- * hold this lock
- */
- public void unlock() {
- sync.unlock();
- }
-
- /**
- * Returns a {@link Condition} instance for use with this
- * {@link Lock} instance.
- *
- * <p>The returned {@link Condition} instance supports the same
- * usages as do the {@link Object} monitor methods ({@link
- * Object#wait() wait}, {@link Object#notify notify}, and {@link
- * Object#notifyAll notifyAll}) when used with the built-in
- * monitor lock.
- *
- * <ul>
- *
- * <li>If this lock is not held when any of the {@link Condition}
- * {@linkplain Condition#await() waiting} or {@linkplain
- * Condition#signal signalling} methods are called, then an {@link
- * IllegalMonitorStateException} is thrown.
- *
- * <li>When the condition {@linkplain Condition#await() waiting}
- * methods are called the lock is released and, before they
- * return, the lock is reacquired and the lock hold count restored
- * to what it was when the method was called.
- *
- * <li>If a thread is {@linkplain Thread#interrupt interrupted}
- * while waiting then the wait will terminate, an {@link
- * InterruptedException} will be thrown, and the thread's
- * interrupted status will be cleared.
- *
- * <li> Waiting threads are signalled in FIFO order.
- *
- * <li>The ordering of lock reacquisition for threads returning
- * from waiting methods is the same as for threads initially
- * acquiring the lock, which is in the default case not specified,
- * but for <em>fair</em> locks favors those threads that have been
- * waiting the longest.
- *
- * </ul>
- *
- * @return the Condition object
- */
- public Condition newCondition() {
- return isFair() ? (Condition)new FIFOCondVar(this) : new CondVar(this);
- }
-
- /**
- * Queries the number of holds on this lock by the current thread.
- *
- * <p>A thread has a hold on a lock for each lock action that is not
- * matched by an unlock action.
- *
- * <p>The hold count information is typically only used for testing and
- * debugging purposes. For example, if a certain section of code should
- * not be entered with the lock already held then we can assert that
- * fact:
- *
- * <pre>
- * class X {
- * ReentrantLock lock = new ReentrantLock();
- * // ...
- * public void m() {
- * assert lock.getHoldCount() == 0;
- * lock.lock();
- * try {
- * // ... method body
- * } finally {
- * lock.unlock();
- * }
- * }
- * }
- * </pre>
- *
- * @return the number of holds on this lock by the current thread,
- * or zero if this lock is not held by the current thread
- */
- public int getHoldCount() {
- return sync.getHoldCount();
- }
-
- /**
- * Queries if this lock is held by the current thread.
- *
- * <p>Analogous to the {@link Thread#holdsLock} method for built-in
- * monitor locks, this method is typically used for debugging and
- * testing. For example, a method that should only be called while
- * a lock is held can assert that this is the case:
- *
- * <pre>
- * class X {
- * ReentrantLock lock = new ReentrantLock();
- * // ...
- *
- * public void m() {
- * assert lock.isHeldByCurrentThread();
- * // ... method body
- * }
- * }
- * </pre>
- *
- * <p>It can also be used to ensure that a reentrant lock is used
- * in a non-reentrant manner, for example:
- *
- * <pre>
- * class X {
- * ReentrantLock lock = new ReentrantLock();
- * // ...
- *
- * public void m() {
- * assert !lock.isHeldByCurrentThread();
- * lock.lock();
- * try {
- * // ... method body
- * } finally {
- * lock.unlock();
- * }
- * }
- * }
- * </pre>
- *
- * @return {@code true} if current thread holds this lock and
- * {@code false} otherwise
- */
- public boolean isHeldByCurrentThread() {
- return sync.isHeldByCurrentThread();
- }
-
- /**
- * Queries if this lock is held by any thread. This method is
- * designed for use in monitoring of the system state,
- * not for synchronization control.
- *
- * @return {@code true} if any thread holds this lock and
- * {@code false} otherwise
- */
- public boolean isLocked() {
- return sync.isLocked();
- }
-
- /**
- * Returns {@code true} if this lock has fairness set true.
- *
- * @return {@code true} if this lock has fairness set true
- */
- public final boolean isFair() {
- return sync.isFair();
- }
-
- /**
- * Returns the thread that currently owns this lock, or
- * {@code null} if not owned. When this method is called by a
- * thread that is not the owner, the return value reflects a
- * best-effort approximation of current lock status. For example,
- * the owner may be momentarily {@code null} even if there are
- * threads trying to acquire the lock but have not yet done so.
- * This method is designed to facilitate construction of
- * subclasses that provide more extensive lock monitoring
- * facilities.
- *
- * @return the owner, or {@code null} if not owned
- */
- protected Thread getOwner() {
- return sync.getOwner();
- }
-
- /**
- * Queries whether any threads are waiting to acquire this lock. Note that
- * because cancellations may occur at any time, a {@code true}
- * return does not guarantee that any other thread will ever
- * acquire this lock. This method is designed primarily for use in
- * monitoring of the system state.
- *
- * @return {@code true} if there may be other threads waiting to
- * acquire the lock
- */
- public final boolean hasQueuedThreads() {
- return sync.hasQueuedThreads();
- }
-
-
- /**
- * Queries whether the given thread is waiting to acquire this
- * lock. Note that because cancellations may occur at any time, a
- * {@code true} return does not guarantee that this thread
- * will ever acquire this lock. This method is designed primarily for use
- * in monitoring of the system state.
- *
- * @param thread the thread
- * @return {@code true} if the given thread is queued waiting for this lock
- * @throws NullPointerException if the thread is null
- */
- public final boolean hasQueuedThread(Thread thread) {
- return sync.isQueued(thread);
- }
-
-
- /**
- * Returns an estimate of the number of threads waiting to
- * acquire this lock. The value is only an estimate because the number of
- * threads may change dynamically while this method traverses
- * internal data structures. This method is designed for use in
- * monitoring of the system state, not for synchronization
- * control.
- *
- * @return the estimated number of threads waiting for this lock
- */
- public final int getQueueLength() {
- return sync.getQueueLength();
- }
-
- /**
- * Returns a collection containing threads that may be waiting to
- * acquire this lock. Because the actual set of threads may change
- * dynamically while constructing this result, the returned
- * collection is only a best-effort estimate. The elements of the
- * returned collection are in no particular order. This method is
- * designed to facilitate construction of subclasses that provide
- * more extensive monitoring facilities.
- *
- * @return the collection of threads
- */
- protected Collection getQueuedThreads() {
- return sync.getQueuedThreads();
- }
-
- /**
- * Queries whether any threads are waiting on the given condition
- * associated with this lock. Note that because timeouts and
- * interrupts may occur at any time, a {@code true} return does
- * not guarantee that a future {@code signal} will awaken any
- * threads. This method is designed primarily for use in
- * monitoring of the system state.
- *
- * @param condition the condition
- * @return {@code true} if there are any waiting threads
- * @throws IllegalMonitorStateException if this lock is not held
- * @throws IllegalArgumentException if the given condition is
- * not associated with this lock
- * @throws NullPointerException if the condition is null
- */
- public boolean hasWaiters(Condition condition) {
- return asCondVar(condition).hasWaiters();
- }
-
- /**
- * Returns an estimate of the number of threads waiting on the
- * given condition associated with this lock. Note that because
- * timeouts and interrupts may occur at any time, the estimate
- * serves only as an upper bound on the actual number of waiters.
- * This method is designed for use in monitoring of the system
- * state, not for synchronization control.
- *
- * @param condition the condition
- * @return the estimated number of waiting threads
- * @throws IllegalMonitorStateException if this lock is not held
- * @throws IllegalArgumentException if the given condition is
- * not associated with this lock
- * @throws NullPointerException if the condition is null
- */
- public int getWaitQueueLength(Condition condition) {
- return asCondVar(condition).getWaitQueueLength();
- }
-
- /**
- * Returns a collection containing those threads that may be
- * waiting on the given condition associated with this lock.
- * Because the actual set of threads may change dynamically while
- * constructing this result, the returned collection is only a
- * best-effort estimate. The elements of the returned collection
- * are in no particular order. This method is designed to
- * facilitate construction of subclasses that provide more
- * extensive condition monitoring facilities.
- *
- * @param condition the condition
- * @return the collection of threads
- * @throws IllegalMonitorStateException if this lock is not held
- * @throws IllegalArgumentException if the given condition is
- * not associated with this lock
- * @throws NullPointerException if the condition is null
- */
- protected Collection getWaitingThreads(Condition condition) {
- return asCondVar(condition).getWaitingThreads();
- }
-
- /**
- * Returns a string identifying this lock, as well as its lock state.
- * The state, in brackets, includes either the String {@code "Unlocked"}
- * or the String {@code "Locked by"} followed by the
- * {@linkplain Thread#getName name} of the owning thread.
- *
- * @return a string identifying this lock, as well as its lock state
- */
- public String toString() {
- Thread o = getOwner();
- return super.toString() + ((o == null) ?
- "[Unlocked]" :
- "[Locked by thread " + o.getName() + "]");
- }
-
- private CondVar asCondVar(Condition condition) {
- if (condition == null)
- throw new NullPointerException();
- if (!(condition instanceof CondVar))
- throw new IllegalArgumentException("not owner");
- CondVar condVar = (CondVar)condition;
- if (condVar.lock != this)
- throw new IllegalArgumentException("not owner");
- return condVar;
- }
-}
diff --git a/src/actors/scala/actors/threadpool/locks/ReentrantReadWriteLock.java b/src/actors/scala/actors/threadpool/locks/ReentrantReadWriteLock.java
deleted file mode 100644
index 914d242100..0000000000
--- a/src/actors/scala/actors/threadpool/locks/ReentrantReadWriteLock.java
+++ /dev/null
@@ -1,1341 +0,0 @@
-/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
- */
-
-package scala.actors.threadpool.locks;
-
-import java.util.HashMap;
-import scala.actors.threadpool.*;
-import scala.actors.threadpool.helpers.*;
-
-/**
- * An implementation of {@link ReadWriteLock} supporting similar
- * semantics to {@link ReentrantLock}.
- * <p>This class has the following properties:
- *
- * <ul>
- * <li><b>Acquisition order</b>
- *
- * <p>The order of entry
- * to the read and write lock is unspecified, subject to reentrancy
- * constraints. A nonfair lock that is continuously contended may
- * indefinitely postpone one or more reader or writer threads, but
- * will normally have higher throughput than a fair lock.
- * <p>
- *
- * DEPARTURE FROM java.util.concurrent: this implementation impose
- * a writer-preference and thus its acquisition order may be different
- * than in java.util.concurrent.
- *
- * <li><b>Reentrancy</b>
- *
- * <p>This lock allows both readers and writers to reacquire read or
- * write locks in the style of a {@link ReentrantLock}. Non-reentrant
- * readers are not allowed until all write locks held by the writing
- * thread have been released.
- *
- * <p>Additionally, a writer can acquire the read lock, but not
- * vice-versa. Among other applications, reentrancy can be useful
- * when write locks are held during calls or callbacks to methods that
- * perform reads under read locks. If a reader tries to acquire the
- * write lock it will never succeed.
- *
- * <li><b>Lock downgrading</b>
- * <p>Reentrancy also allows downgrading from the write lock to a read lock,
- * by acquiring the write lock, then the read lock and then releasing the
- * write lock. However, upgrading from a read lock to the write lock is
- * <b>not</b> possible.
- *
- * <li><b>Interruption of lock acquisition</b>
- * <p>The read lock and write lock both support interruption during lock
- * acquisition.
- *
- * <li><b>{@link Condition} support</b>
- * <p>The write lock provides a {@link Condition} implementation that
- * behaves in the same way, with respect to the write lock, as the
- * {@link Condition} implementation provided by
- * {@link ReentrantLock#newCondition} does for {@link ReentrantLock}.
- * This {@link Condition} can, of course, only be used with the write lock.
- *
- * <p>The read lock does not support a {@link Condition} and
- * {@code readLock().newCondition()} throws
- * {@code UnsupportedOperationException}.
- *
- * <li><b>Instrumentation</b>
- * <p>This class supports methods to determine whether locks
- * are held or contended. These methods are designed for monitoring
- * system state, not for synchronization control.
- * </ul>
- *
- * <p>Serialization of this class behaves in the same way as built-in
- * locks: a deserialized lock is in the unlocked state, regardless of
- * its state when serialized.
- *
- * <p><b>Sample usages</b>. Here is a code sketch showing how to exploit
- * reentrancy to perform lock downgrading after updating a cache (exception
- * handling is elided for simplicity):
- * <pre>
- * class CachedData {
- * Object data;
- * volatile boolean cacheValid;
- * ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
- *
- * void processCachedData() {
- * rwl.readLock().lock();
- * if (!cacheValid) {
- * // Must release read lock before acquiring write lock
- * rwl.readLock().unlock();
- * rwl.writeLock().lock();
- * // Recheck state because another thread might have acquired
- * // write lock and changed state before we did.
- * if (!cacheValid) {
- * data = ...
- * cacheValid = true;
- * }
- * // Downgrade by acquiring read lock before releasing write lock
- * rwl.readLock().lock();
- * rwl.writeLock().unlock(); // Unlock write, still hold read
- * }
- *
- * use(data);
- * rwl.readLock().unlock();
- * }
- * }
- * </pre>
- *
- * ReentrantReadWriteLocks can be used to improve concurrency in some
- * uses of some kinds of Collections. This is typically worthwhile
- * only when the collections are expected to be large, accessed by
- * more reader threads than writer threads, and entail operations with
- * overhead that outweighs synchronization overhead. For example, here
- * is a class using a TreeMap that is expected to be large and
- * concurrently accessed.
- *
- * <pre>{@code
- * class RWDictionary {
- * private final Map<String, Data> m = new TreeMap<String, Data>();
- * private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
- * private final Lock r = rwl.readLock();
- * private final Lock w = rwl.writeLock();
- *
- * public Data get(String key) {
- * r.lock();
- * try { return m.get(key); }
- * finally { r.unlock(); }
- * }
- * public String[] allKeys() {
- * r.lock();
- * try { return m.keySet().toArray(); }
- * finally { r.unlock(); }
- * }
- * public Data put(String key, Data value) {
- * w.lock();
- * try { return m.put(key, value); }
- * finally { w.unlock(); }
- * }
- * public void clear() {
- * w.lock();
- * try { m.clear(); }
- * finally { w.unlock(); }
- * }
- * }}</pre>
- *
- * <h3>Implementation Notes</h3>
- *
- * <p>This lock supports a maximum of 65535 recursive write locks
- * and 65535 read locks. Attempts to exceed these limits result in
- * {@link Error} throws from locking methods.
- *
- * @since 1.5
- * @author Doug Lea
- *
- */
-public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializable {
- private static final long serialVersionUID = -3463448656717690166L;
-
- final ReadLock readerLock_ = new ReadLock(this);
- final WriteLock writerLock_ = new WriteLock(this);
-
- final Sync sync;
-
- /**
- * Creates a new {@code ReentrantReadWriteLock} with
- * default (nonfair) ordering properties.
- */
- public ReentrantReadWriteLock() {
- this.sync = new NonfairSync();
- }
-
- public Lock writeLock() { return writerLock_; }
- public Lock readLock() { return readerLock_; }
-
- /**
- * Synchronization implementation for ReentrantReadWriteLock.
- * Subclassed into fair and nonfair versions.
- */
- private abstract static class Sync implements java.io.Serializable {
-
- private static final int NONE = 0;
- private static final int READER = 1;
- private static final int WRITER = 2;
-
- transient int activeReaders_ = 0;
- transient Thread activeWriter_ = null;
- transient int waitingReaders_ = 0;
- transient int waitingWriters_ = 0;
-
- /** Number of acquires on write lock by activeWriter_ thread **/
- transient int writeHolds_ = 0;
-
- /** Number of acquires on read lock by any reader thread **/
- transient HashMap<Thread, Integer> readers_ = new HashMap<Thread, Integer>();
-
- /** cache/reuse the special Integer value one to speed up readlocks **/
- static final Integer IONE = new Integer(1);
-
- Sync() {}
-
- /*
- Each of these variants is needed to maintain atomicity
- of wait counts during wait loops. They could be
- made faster by manually inlining each other. We hope that
- compilers do this for us though.
- */
-
- synchronized boolean startReadFromNewReader() {
- boolean pass = startRead();
- if (!pass) ++waitingReaders_;
- return pass;
- }
-
- synchronized boolean startWriteFromNewWriter() {
- boolean pass = startWrite();
- if (!pass) ++waitingWriters_;
- return pass;
- }
-
- synchronized boolean startReadFromWaitingReader() {
- boolean pass = startRead();
- if (pass) --waitingReaders_;
- return pass;
- }
-
- synchronized boolean startWriteFromWaitingWriter() {
- boolean pass = startWrite();
- if (pass) --waitingWriters_;
- return pass;
- }
-
- /*
- A bunch of small synchronized methods are needed
- to allow communication from the Lock objects
- back to this object, that serves as controller
- */
-
- synchronized void cancelledWaitingReader() { --waitingReaders_; }
- synchronized void cancelledWaitingWriter() { --waitingWriters_; }
-
- boolean allowReader() {
- return (activeWriter_ == null && waitingWriters_ == 0) ||
- activeWriter_ == Thread.currentThread();
- }
-
- synchronized boolean startRead() {
- Thread t = Thread.currentThread();
- Object c = readers_.get(t);
- if (c != null) { // already held -- just increment hold count
- readers_.put(t, new Integer( ( (Integer) (c)).intValue() + 1));
- ++activeReaders_;
- return true;
- }
- else if (allowReader()) {
- readers_.put(t, IONE);
- ++activeReaders_;
- return true;
- }
- else
- return false;
- }
-
- synchronized boolean startWrite() {
- if (activeWriter_ == Thread.currentThread()) { // already held; re-acquire
- ++writeHolds_;
- return true;
- }
- else if (writeHolds_ == 0) {
- if (activeReaders_ == 0 ||
- (readers_.size() == 1 &&
- readers_.get(Thread.currentThread()) != null)) {
- activeWriter_ = Thread.currentThread();
- writeHolds_ = 1;
- return true;
- }
- else
- return false;
- }
- else
- return false;
- }
-
- synchronized int endRead() {
- Thread t = Thread.currentThread();
- Object c = readers_.get(t);
- if (c == null)
- throw new IllegalMonitorStateException();
- --activeReaders_;
- if (c != IONE) { // more than one hold; decrement count
- int h = ( (Integer) (c)).intValue() - 1;
- Integer ih = (h == 1) ? IONE : new Integer(h);
- readers_.put(t, ih);
- return NONE;
- }
- else {
- readers_.remove(t);
-
- if (writeHolds_ > 0) // a write lock is still held by current thread
- return NONE;
- else if (activeReaders_ == 0 && waitingWriters_ > 0)
- return WRITER;
- else
- return NONE;
- }
- }
-
- synchronized int endWrite() {
- if (activeWriter_ != Thread.currentThread()) {
- throw new IllegalMonitorStateException();
- }
- --writeHolds_;
- if (writeHolds_ > 0) // still being held
- return NONE;
- else {
- activeWriter_ = null;
- if (waitingReaders_ > 0 && allowReader())
- return READER;
- else if (waitingWriters_ > 0)
- return WRITER;
- else
- return NONE;
- }
- }
-
- synchronized Thread getOwner() {
- return activeWriter_;
- }
-
- synchronized int getReadLockCount() {
- return activeReaders_;
- }
-
- synchronized boolean isWriteLocked() {
- return activeWriter_ != null;
- }
-
- synchronized boolean isWriteLockedByCurrentThread() {
- return activeWriter_ == Thread.currentThread();
- }
-
- synchronized int getWriteHoldCount() {
- return isWriteLockedByCurrentThread() ? writeHolds_ : 0;
- }
-
- synchronized int getReadHoldCount() {
- if (activeReaders_ == 0) return 0;
- Thread t = Thread.currentThread();
- Integer i = readers_.get(t);
- return (i == null) ? 0 : i.intValue();
- }
-
- final synchronized boolean hasQueuedThreads() {
- return waitingWriters_ > 0 || waitingReaders_ > 0;
- }
-
- final synchronized int getQueueLength() {
- return waitingWriters_ + waitingReaders_;
- }
-
- private void readObject(java.io.ObjectInputStream in)
- throws java.io.IOException, ClassNotFoundException {
- in.defaultReadObject();
- // readers_ is transient, need to reinitialize. Let's flush the memory
- // and ensure visibility by synchronizing (all other accesses to
- // readers_ are also synchronized on "this")
- synchronized (this) {
- readers_ = new HashMap<Thread, Integer>();
- }
- }
- }
-
- /**
- * Nonfair version of Sync
- */
- private static class NonfairSync extends Sync {
- private static final long serialVersionUID = -2392241841540339773L;
-
- NonfairSync() {}
- }
-
- /**
- * The lock returned by method {@link ReentrantReadWriteLock#readLock}.
- */
- public static class ReadLock implements Lock, java.io.Serializable {
-
- private static final long serialVersionUID = -5992448646407690164L;
-
- final ReentrantReadWriteLock lock;
-
- /**
- * Constructor for use by subclasses
- *
- * @param lock the outer lock object
- * @throws NullPointerException if the lock is null
- */
- protected ReadLock(ReentrantReadWriteLock lock) {
- if (lock == null) throw new NullPointerException();
- this.lock = lock;
- }
-
- /**
- * Acquires the read lock.
- *
- * <p>Acquires the read lock if the write lock is not held by
- * another thread and returns immediately.
- *
- * <p>If the write lock is held by another thread then
- * the current thread becomes disabled for thread scheduling
- * purposes and lies dormant until the read lock has been acquired.
- */
- public void lock() {
- synchronized (this) {
- if (lock.sync.startReadFromNewReader()) return;
- boolean wasInterrupted = Thread.interrupted();
- try {
- while (true) {
- try {
- ReadLock.this.wait();
- }
- catch (InterruptedException ex) {
- wasInterrupted = true;
- // no need to propagate the potentially masked
- // signal, since readers are always notified all
- }
- if (lock.sync.startReadFromWaitingReader()) return;
- }
- }
- finally {
- if (wasInterrupted) Thread.currentThread().interrupt();
- }
- }
- }
-
- /**
- * Acquires the read lock unless the current thread is
- * {@linkplain Thread#interrupt interrupted}.
- *
- * <p>Acquires the read lock if the write lock is not held
- * by another thread and returns immediately.
- *
- * <p>If the write lock is held by another thread then the
- * current thread becomes disabled for thread scheduling
- * purposes and lies dormant until one of two things happens:
- *
- * <ul>
- *
- * <li>The read lock is acquired by the current thread; or
- *
- * <li>Some other thread {@linkplain Thread#interrupt interrupts}
- * the current thread.
- *
- * </ul>
- *
- * <p>If the current thread:
- *
- * <ul>
- *
- * <li>has its interrupted status set on entry to this method; or
- *
- * <li>is {@linkplain Thread#interrupt interrupted} while
- * acquiring the read lock,
- *
- * </ul>
- *
- * then {@link InterruptedException} is thrown and the current
- * thread's interrupted status is cleared.
- *
- * <p>In this implementation, as this method is an explicit
- * interruption point, preference is given to responding to
- * the interrupt over normal or reentrant acquisition of the
- * lock.
- *
- * @throws InterruptedException if the current thread is interrupted
- */
- public void lockInterruptibly() throws InterruptedException {
- if (Thread.interrupted()) throw new InterruptedException();
- InterruptedException ie = null;
- synchronized (this) {
- if (!lock.sync.startReadFromNewReader()) {
- for (; ; ) {
- try {
- ReadLock.this.wait();
- if (lock.sync.startReadFromWaitingReader())
- return;
- }
- catch (InterruptedException ex) {
- lock.sync.cancelledWaitingReader();
- ie = ex;
- break;
- }
- }
- }
- }
- if (ie != null) {
- // fall through outside synch on interrupt.
- // This notification is not really needed here,
- // but may be in plausible subclasses
- lock.writerLock_.signalWaiters();
- throw ie;
- }
- }
-
- /**
- * Acquires the read lock only if the write lock is not held by
- * another thread at the time of invocation.
- *
- * <p>Acquires the read lock if the write lock is not held by
- * another thread and returns immediately with the value
- * {@code true}. Even when this lock has been set to use a
- * fair ordering policy, a call to {@code tryLock()}
- * <em>will</em> immediately acquire the read lock if it is
- * available, whether or not other threads are currently
- * waiting for the read lock. This &quot;barging&quot; behavior
- * can be useful in certain circumstances, even though it
- * breaks fairness. If you want to honor the fairness setting
- * for this lock, then use {@link #tryLock(long, TimeUnit)
- * tryLock(0, TimeUnit.SECONDS) } which is almost equivalent
- * (it also detects interruption).
- *
- * <p>If the write lock is held by another thread then
- * this method will return immediately with the value
- * {@code false}.
- *
- * @return {@code true} if the read lock was acquired
- */
- public boolean tryLock() {
- return lock.sync.startRead();
- }
-
- /**
- * Acquires the read lock if the write lock is not held by
- * another thread within the given waiting time and the
- * current thread has not been {@linkplain Thread#interrupt
- * interrupted}.
- *
- * <p>Acquires the read lock if the write lock is not held by
- * another thread and returns immediately with the value
- * {@code true}. If this lock has been set to use a fair
- * ordering policy then an available lock <em>will not</em> be
- * acquired if any other threads are waiting for the
- * lock. This is in contrast to the {@link #tryLock()}
- * method. If you want a timed {@code tryLock} that does
- * permit barging on a fair lock then combine the timed and
- * un-timed forms together:
- *
- * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
- * </pre>
- *
- * <p>If the write lock is held by another thread then the
- * current thread becomes disabled for thread scheduling
- * purposes and lies dormant until one of three things happens:
- *
- * <ul>
- *
- * <li>The read lock is acquired by the current thread; or
- *
- * <li>Some other thread {@linkplain Thread#interrupt interrupts}
- * the current thread; or
- *
- * <li>The specified waiting time elapses.
- *
- * </ul>
- *
- * <p>If the read lock is acquired then the value {@code true} is
- * returned.
- *
- * <p>If the current thread:
- *
- * <ul>
- *
- * <li>has its interrupted status set on entry to this method; or
- *
- * <li>is {@linkplain Thread#interrupt interrupted} while
- * acquiring the read lock,
- *
- * </ul> then {@link InterruptedException} is thrown and the
- * current thread's interrupted status is cleared.
- *
- * <p>If the specified waiting time elapses then the value
- * {@code false} is returned. If the time is less than or
- * equal to zero, the method will not wait at all.
- *
- * <p>In this implementation, as this method is an explicit
- * interruption point, preference is given to responding to
- * the interrupt over normal or reentrant acquisition of the
- * lock, and over reporting the elapse of the waiting time.
- *
- * @param timeout the time to wait for the read lock
- * @param unit the time unit of the timeout argument
- * @return {@code true} if the read lock was acquired
- * @throws InterruptedException if the current thread is interrupted
- * @throws NullPointerException if the time unit is null
- *
- */
- public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
- if (Thread.interrupted()) throw new InterruptedException();
- InterruptedException ie = null;
- long nanos = unit.toNanos(timeout);
- synchronized (this) {
- if (nanos <= 0)
- return lock.sync.startRead();
- else if (lock.sync.startReadFromNewReader())
- return true;
- else {
- long deadline = Utils.nanoTime() + nanos;
- for (; ; ) {
- try {
- TimeUnit.NANOSECONDS.timedWait(ReadLock.this, nanos);
- }
- catch (InterruptedException ex) {
- lock.sync.cancelledWaitingReader();
- ie = ex;
- break;
- }
- if (lock.sync.startReadFromWaitingReader())
- return true;
- else {
- nanos = deadline - Utils.nanoTime();
- if (nanos <= 0) {
- lock.sync.cancelledWaitingReader();
- break;
- }
- }
- }
- }
- }
- // safeguard on interrupt or timeout:
- lock.writerLock_.signalWaiters();
- if (ie != null)
- throw ie;
- else
- return false; // timed out
- }
-
- /**
- * Attempts to release this lock.
- *
- * <p> If the number of readers is now zero then the lock
- * is made available for write lock attempts.
- */
- public void unlock() {
- switch (lock.sync.endRead()) {
- case Sync.NONE: return;
- case Sync.READER: lock.readerLock_.signalWaiters(); return;
- case Sync.WRITER: lock.writerLock_.signalWaiters(); return;
- }
- }
-
- /**
- * Throws {@code UnsupportedOperationException} because
- * {@code ReadLocks} do not support conditions.
- *
- * @throws UnsupportedOperationException always
- */
- public Condition newCondition() {
- throw new UnsupportedOperationException();
- }
-
- synchronized void signalWaiters() {
- notifyAll();
- }
-
- /**
- * Returns a string identifying this lock, as well as its lock state.
- * The state, in brackets, includes the String {@code "Read locks ="}
- * followed by the number of held read locks.
- *
- * @return a string identifying this lock, as well as its lock state
- */
- public String toString() {
- int r = lock.getReadLockCount();
- return super.toString() +
- "[Read locks = " + r + "]";
- }
-
- }
-
- /**
- * The lock returned by method {@link ReentrantReadWriteLock#writeLock}.
- */
- public static class WriteLock implements Lock, CondVar.ExclusiveLock,
- java.io.Serializable {
-
- private static final long serialVersionUID = -4992448646407690164L;
- final ReentrantReadWriteLock lock;
-
- /**
- * Constructor for use by subclasses
- *
- * @param lock the outer lock object
- * @throws NullPointerException if the lock is null
- */
- protected WriteLock(ReentrantReadWriteLock lock) {
- if (lock == null) throw new NullPointerException();
- this.lock = lock;
- }
-
- /**
- * Acquires the write lock.
- *
- * <p>Acquires the write lock if neither the read nor write lock
- * are held by another thread
- * and returns immediately, setting the write lock hold count to
- * one.
- *
- * <p>If the current thread already holds the write lock then the
- * hold count is incremented by one and the method returns
- * immediately.
- *
- * <p>If the lock is held by another thread then the current
- * thread becomes disabled for thread scheduling purposes and
- * lies dormant until the write lock has been acquired, at which
- * time the write lock hold count is set to one.
- */
- public void lock() {
- synchronized (this) {
- if (lock.sync.startWriteFromNewWriter()) return;
- boolean wasInterrupted = Thread.interrupted();
- try {
- while (true) {
- try {
- WriteLock.this.wait();
- }
- catch (InterruptedException ex) {
- wasInterrupted = true;
- // no need to notify; if we were notified,
- // we will act as notified, and succeed in
- // startWrite and return
- }
- if (lock.sync.startWriteFromWaitingWriter()) return;
- }
- }
- finally {
- if (wasInterrupted) Thread.currentThread().interrupt();
- }
- }
- }
-
- /**
- * Acquires the write lock unless the current thread is
- * {@linkplain Thread#interrupt interrupted}.
- *
- * <p>Acquires the write lock if neither the read nor write lock
- * are held by another thread
- * and returns immediately, setting the write lock hold count to
- * one.
- *
- * <p>If the current thread already holds this lock then the
- * hold count is incremented by one and the method returns
- * immediately.
- *
- * <p>If the lock is held by another thread then the current
- * thread becomes disabled for thread scheduling purposes and
- * lies dormant until one of two things happens:
- *
- * <ul>
- *
- * <li>The write lock is acquired by the current thread; or
- *
- * <li>Some other thread {@linkplain Thread#interrupt interrupts}
- * the current thread.
- *
- * </ul>
- *
- * <p>If the write lock is acquired by the current thread then the
- * lock hold count is set to one.
- *
- * <p>If the current thread:
- *
- * <ul>
- *
- * <li>has its interrupted status set on entry to this method;
- * or
- *
- * <li>is {@linkplain Thread#interrupt interrupted} while
- * acquiring the write lock,
- *
- * </ul>
- *
- * then {@link InterruptedException} is thrown and the current
- * thread's interrupted status is cleared.
- *
- * <p>In this implementation, as this method is an explicit
- * interruption point, preference is given to responding to
- * the interrupt over normal or reentrant acquisition of the
- * lock.
- *
- * @throws InterruptedException if the current thread is interrupted
- */
- public void lockInterruptibly() throws InterruptedException {
- if (Thread.interrupted()) throw new InterruptedException();
- InterruptedException ie = null;
- synchronized (this) {
- if (!lock.sync.startWriteFromNewWriter()) {
- for (; ; ) {
- try {
- WriteLock.this.wait();
- if (lock.sync.startWriteFromWaitingWriter())
- return;
- }
- catch (InterruptedException ex) {
- lock.sync.cancelledWaitingWriter();
- WriteLock.this.notify();
- ie = ex;
- break;
- }
- }
- }
- }
- if (ie != null) {
- // Fall through outside synch on interrupt.
- // On exception, we may need to signal readers.
- // It is not worth checking here whether it is strictly necessary.
- lock.readerLock_.signalWaiters();
- throw ie;
- }
- }
-
- /**
- * Acquires the write lock only if it is not held by another thread
- * at the time of invocation.
- *
- * <p>Acquires the write lock if neither the read nor write lock
- * are held by another thread
- * and returns immediately with the value {@code true},
- * setting the write lock hold count to one. Even when this lock has
- * been set to use a fair ordering policy, a call to
- * {@code tryLock()} <em>will</em> immediately acquire the
- * lock if it is available, whether or not other threads are
- * currently waiting for the write lock. This &quot;barging&quot;
- * behavior can be useful in certain circumstances, even
- * though it breaks fairness. If you want to honor the
- * fairness setting for this lock, then use {@link
- * #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }
- * which is almost equivalent (it also detects interruption).
- *
- * <p> If the current thread already holds this lock then the
- * hold count is incremented by one and the method returns
- * {@code true}.
- *
- * <p>If the lock is held by another thread then this method
- * will return immediately with the value {@code false}.
- *
- * @return {@code true} if the lock was free and was acquired
- * by the current thread, or the write lock was already held
- * by the current thread; and {@code false} otherwise.
- */
- public boolean tryLock() {
- return lock.sync.startWrite();
- }
-
- /**
- * Acquires the write lock if it is not held by another thread
- * within the given waiting time and the current thread has
- * not been {@linkplain Thread#interrupt interrupted}.
- *
- * <p>Acquires the write lock if neither the read nor write lock
- * are held by another thread
- * and returns immediately with the value {@code true},
- * setting the write lock hold count to one. If this lock has been
- * set to use a fair ordering policy then an available lock
- * <em>will not</em> be acquired if any other threads are
- * waiting for the write lock. This is in contrast to the {@link
- * #tryLock()} method. If you want a timed {@code tryLock}
- * that does permit barging on a fair lock then combine the
- * timed and un-timed forms together:
- *
- * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
- * </pre>
- *
- * <p>If the current thread already holds this lock then the
- * hold count is incremented by one and the method returns
- * {@code true}.
- *
- * <p>If the lock is held by another thread then the current
- * thread becomes disabled for thread scheduling purposes and
- * lies dormant until one of three things happens:
- *
- * <ul>
- *
- * <li>The write lock is acquired by the current thread; or
- *
- * <li>Some other thread {@linkplain Thread#interrupt interrupts}
- * the current thread; or
- *
- * <li>The specified waiting time elapses
- *
- * </ul>
- *
- * <p>If the write lock is acquired then the value {@code true} is
- * returned and the write lock hold count is set to one.
- *
- * <p>If the current thread:
- *
- * <ul>
- *
- * <li>has its interrupted status set on entry to this method;
- * or
- *
- * <li>is {@linkplain Thread#interrupt interrupted} while
- * acquiring the write lock,
- *
- * </ul>
- *
- * then {@link InterruptedException} is thrown and the current
- * thread's interrupted status is cleared.
- *
- * <p>If the specified waiting time elapses then the value
- * {@code false} is returned. If the time is less than or
- * equal to zero, the method will not wait at all.
- *
- * <p>In this implementation, as this method is an explicit
- * interruption point, preference is given to responding to
- * the interrupt over normal or reentrant acquisition of the
- * lock, and over reporting the elapse of the waiting time.
- *
- * @param timeout the time to wait for the write lock
- * @param unit the time unit of the timeout argument
- *
- * @return {@code true} if the lock was free and was acquired
- * by the current thread, or the write lock was already held by the
- * current thread; and {@code false} if the waiting time
- * elapsed before the lock could be acquired.
- *
- * @throws InterruptedException if the current thread is interrupted
- * @throws NullPointerException if the time unit is null
- *
- */
- public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
- if (Thread.interrupted()) throw new InterruptedException();
- InterruptedException ie = null;
- long nanos = unit.toNanos(timeout);
- synchronized (this) {
- if (nanos <= 0)
- return lock.sync.startWrite();
- else if (lock.sync.startWriteFromNewWriter())
- return true;
- else {
- long deadline = Utils.nanoTime() + nanos;
- for (; ; ) {
- try {
- TimeUnit.NANOSECONDS.timedWait(WriteLock.this, nanos);
- }
- catch (InterruptedException ex) {
- lock.sync.cancelledWaitingWriter();
- WriteLock.this.notify();
- ie = ex;
- break;
- }
- if (lock.sync.startWriteFromWaitingWriter())
- return true;
- else {
- nanos = deadline - Utils.nanoTime();
- if (nanos <= 0) {
- lock.sync.cancelledWaitingWriter();
- WriteLock.this.notify();
- break;
- }
- }
- }
- }
- }
-
- lock.readerLock_.signalWaiters();
- if (ie != null)
- throw ie;
- else
- return false; // timed out
- }
-
- /**
- * Attempts to release this lock.
- *
- * <p>If the current thread is the holder of this lock then
- * the hold count is decremented. If the hold count is now
- * zero then the lock is released. If the current thread is
- * not the holder of this lock then {@link
- * IllegalMonitorStateException} is thrown.
- *
- * @throws IllegalMonitorStateException if the current thread does not
- * hold this lock.
- */
- public void unlock() {
- switch (lock.sync.endWrite()) {
- case Sync.NONE: return;
- case Sync.READER: lock.readerLock_.signalWaiters(); return;
- case Sync.WRITER: lock.writerLock_.signalWaiters(); return;
- }
- }
-
- /**
- * Returns a {@link Condition} instance for use with this
- * {@link Lock} instance.
- * <p>The returned {@link Condition} instance supports the same
- * usages as do the {@link Object} monitor methods ({@link
- * Object#wait() wait}, {@link Object#notify notify}, and {@link
- * Object#notifyAll notifyAll}) when used with the built-in
- * monitor lock.
- *
- * <ul>
- *
- * <li>If this write lock is not held when any {@link
- * Condition} method is called then an {@link
- * IllegalMonitorStateException} is thrown. (Read locks are
- * held independently of write locks, so are not checked or
- * affected. However it is essentially always an error to
- * invoke a condition waiting method when the current thread
- * has also acquired read locks, since other threads that
- * could unblock it will not be able to acquire the write
- * lock.)
- *
- * <li>When the condition {@linkplain Condition#await() waiting}
- * methods are called the write lock is released and, before
- * they return, the write lock is reacquired and the lock hold
- * count restored to what it was when the method was called.
- *
- * <li>If a thread is {@linkplain Thread#interrupt interrupted} while
- * waiting then the wait will terminate, an {@link
- * InterruptedException} will be thrown, and the thread's
- * interrupted status will be cleared.
- *
- * <li> Waiting threads are signalled in FIFO order.
- *
- * <li>The ordering of lock reacquisition for threads returning
- * from waiting methods is the same as for threads initially
- * acquiring the lock, which is in the default case not specified,
- * but for <em>fair</em> locks favors those threads that have been
- * waiting the longest.
- *
- * </ul>
- *
- * @return the Condition object
- */
- public Condition newCondition() {
- return new CondVar(this);
- }
-
- synchronized void signalWaiters() {
- notify();
- }
-
- /**
- * Returns a string identifying this lock, as well as its lock
- * state. The state, in brackets includes either the String
- * {@code "Unlocked"} or the String {@code "Locked by"}
- * followed by the {@linkplain Thread#getName name} of the owning thread.
- *
- * @return a string identifying this lock, as well as its lock state
- */
- public String toString() {
- Thread o = lock.getOwner();
- return super.toString() + ((o == null) ?
- "[Unlocked]" :
- "[Locked by thread " + o.getName() + "]");
- }
-
- /**
- * Queries if this write lock is held by the current thread.
- * Identical in effect to {@link
- * ReentrantReadWriteLock#isWriteLockedByCurrentThread}.
- *
- * @return {@code true} if the current thread holds this lock and
- * {@code false} otherwise
- * @since 1.6
- */
- public boolean isHeldByCurrentThread() {
- return lock.sync.isWriteLockedByCurrentThread();
- }
-
- /**
- * Queries the number of holds on this write lock by the current
- * thread. A thread has a hold on a lock for each lock action
- * that is not matched by an unlock action. Identical in effect
- * to {@link ReentrantReadWriteLock#getWriteHoldCount}.
- *
- * @return the number of holds on this lock by the current thread,
- * or zero if this lock is not held by the current thread
- * @since 1.6
- */
- public int getHoldCount() {
- return lock.sync.getWriteHoldCount();
- }
-
- }
-
- // Instrumentation and status
-
- /**
- * Returns {@code true} if this lock has fairness set true.
- *
- * @return {@code true} if this lock has fairness set true
- */
- public final boolean isFair() {
- return false;
- }
-
- /**
- * Returns the thread that currently owns the write lock, or
- * {@code null} if not owned. When this method is called by a
- * thread that is not the owner, the return value reflects a
- * best-effort approximation of current lock status. For example,
- * the owner may be momentarily {@code null} even if there are
- * threads trying to acquire the lock but have not yet done so.
- * This method is designed to facilitate construction of
- * subclasses that provide more extensive lock monitoring
- * facilities.
- *
- * @return the owner, or {@code null} if not owned
- */
- protected Thread getOwner() {
- return sync.getOwner();
- }
-
- /**
- * Queries the number of read locks held for this lock. This
- * method is designed for use in monitoring system state, not for
- * synchronization control.
- * @return the number of read locks held.
- */
- public int getReadLockCount() {
- return sync.getReadLockCount();
- }
-
- /**
- * Queries if the write lock is held by any thread. This method is
- * designed for use in monitoring system state, not for
- * synchronization control.
- *
- * @return {@code true} if any thread holds the write lock and
- * {@code false} otherwise
- */
- public boolean isWriteLocked() {
- return sync.isWriteLocked();
- }
-
- /**
- * Queries if the write lock is held by the current thread.
- *
- * @return {@code true} if the current thread holds the write lock and
- * {@code false} otherwise
- */
- public boolean isWriteLockedByCurrentThread() {
- return sync.isWriteLockedByCurrentThread();
- }
-
- /**
- * Queries the number of reentrant write holds on this lock by the
- * current thread. A writer thread has a hold on a lock for
- * each lock action that is not matched by an unlock action.
- *
- * @return the number of holds on the write lock by the current thread,
- * or zero if the write lock is not held by the current thread
- */
- public int getWriteHoldCount() {
- return sync.getWriteHoldCount();
- }
-
- /**
- * Queries the number of reentrant read holds on this lock by the
- * current thread. A reader thread has a hold on a lock for
- * each lock action that is not matched by an unlock action.
- *
- * @return the number of holds on the read lock by the current thread,
- * or zero if the read lock is not held by the current thread
- * @since 1.6
- */
- public int getReadHoldCount() {
- return sync.getReadHoldCount();
- }
-
-
-// /**
-// * Returns a collection containing threads that may be waiting to
-// * acquire the write lock. Because the actual set of threads may
-// * change dynamically while constructing this result, the returned
-// * collection is only a best-effort estimate. The elements of the
-// * returned collection are in no particular order. This method is
-// * designed to facilitate construction of subclasses that provide
-// * more extensive lock monitoring facilities.
-// * @return the collection of threads
-// */
-// protected Collection getQueuedWriterThreads() {
-// return sync.getExclusiveQueuedThreads();
-// }
-//
-// /**
-// * Returns a collection containing threads that may be waiting to
-// * acquire the read lock. Because the actual set of threads may
-// * change dynamically while constructing this result, the returned
-// * collection is only a best-effort estimate. The elements of the
-// * returned collection are in no particular order. This method is
-// * designed to facilitate construction of subclasses that provide
-// * more extensive lock monitoring facilities.
-// * @return the collection of threads
-// */
-// protected Collection getQueuedReaderThreads() {
-// return sync.getSharedQueuedThreads();
-// }
-//
- /**
- * Queries whether any threads are waiting to acquire the read or
- * write lock. Note that because cancellations may occur at any
- * time, a {@code true} return does not guarantee that any other
- * thread will ever acquire a lock. This method is designed
- * primarily for use in monitoring of the system state.
- *
- * @return {@code true} if there may be other threads waiting to
- * acquire the lock
- */
- public final boolean hasQueuedThreads() {
- return sync.hasQueuedThreads();
- }
-//
-// /**
-// * Queries whether the given thread is waiting to acquire either
-// * the read or write lock. Note that because cancellations may
-// * occur at any time, a <tt>true</tt> return does not guarantee
-// * that this thread will ever acquire a lock. This method is
-// * designed primarily for use in monitoring of the system state.
-// *
-// * @param thread the thread
-// * @return true if the given thread is queued waiting for this lock.
-// * @throws NullPointerException if thread is null
-// */
-// public final boolean hasQueuedThread(Thread thread) {
-// return sync.isQueued(thread);
-// }
-
- /**
- * Returns an estimate of the number of threads waiting to acquire
- * either the read or write lock. The value is only an estimate
- * because the number of threads may change dynamically while this
- * method traverses internal data structures. This method is
- * designed for use in monitoring of the system state, not for
- * synchronization control.
- *
- * @return the estimated number of threads waiting for this lock
- */
- public final int getQueueLength() {
- return sync.getQueueLength();
- }
-
-// /**
-// * Returns a collection containing threads that may be waiting to
-// * acquire either the read or write lock. Because the actual set
-// * of threads may change dynamically while constructing this
-// * result, the returned collection is only a best-effort estimate.
-// * The elements of the returned collection are in no particular
-// * order. This method is designed to facilitate construction of
-// * subclasses that provide more extensive monitoring facilities.
-// * @return the collection of threads
-// */
-// protected Collection getQueuedThreads() {
-// return sync.getQueuedThreads();
-// }
-//
-// /**
-// * Queries whether any threads are waiting on the given condition
-// * associated with the write lock. Note that because timeouts and
-// * interrupts may occur at any time, a <tt>true</tt> return does
-// * not guarantee that a future <tt>signal</tt> will awaken any
-// * threads. This method is designed primarily for use in
-// * monitoring of the system state.
-// * @param condition the condition
-// * @return <tt>true</tt> if there are any waiting threads.
-// * @throws IllegalMonitorStateException if this lock
-// * is not held
-// * @throws IllegalArgumentException if the given condition is
-// * not associated with this lock
-// * @throws NullPointerException if condition null
-// */
-// public boolean hasWaiters(Condition condition) {
-// if (condition == null)
-// throw new NullPointerException();
-// if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
-// throw new IllegalArgumentException("not owner");
-// return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
-// }
-
-// /**
-// * Returns an estimate of the number of threads waiting on the
-// * given condition associated with the write lock. Note that because
-// * timeouts and interrupts may occur at any time, the estimate
-// * serves only as an upper bound on the actual number of waiters.
-// * This method is designed for use in monitoring of the system
-// * state, not for synchronization control.
-// * @param condition the condition
-// * @return the estimated number of waiting threads.
-// * @throws IllegalMonitorStateException if this lock
-// * is not held
-// * @throws IllegalArgumentException if the given condition is
-// * not associated with this lock
-// * @throws NullPointerException if condition null
-// */
-// public int getWaitQueueLength(Condition condition) {
-// if (condition == null)
-// throw new NullPointerException();
-// if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
-// throw new IllegalArgumentException("not owner");
-// return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
-// }
-//
-// /**
-// * Returns a collection containing those threads that may be
-// * waiting on the given condition associated with the write lock.
-// * Because the actual set of threads may change dynamically while
-// * constructing this result, the returned collection is only a
-// * best-effort estimate. The elements of the returned collection
-// * are in no particular order. This method is designed to
-// * facilitate construction of subclasses that provide more
-// * extensive condition monitoring facilities.
-// * @param condition the condition
-// * @return the collection of threads
-// * @throws IllegalMonitorStateException if this lock
-// * is not held
-// * @throws IllegalArgumentException if the given condition is
-// * not associated with this lock
-// * @throws NullPointerException if condition null
-// */
-// protected Collection getWaitingThreads(Condition condition) {
-// if (condition == null)
-// throw new NullPointerException();
-// if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
-// throw new IllegalArgumentException("not owner");
-// return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
-// }
-
- /**
- * Returns a string identifying this lock, as well as its lock state.
- * The state, in brackets, includes the String {@code "Write locks ="}
- * followed by the number of reentrantly held write locks, and the
- * String {@code "Read locks ="} followed by the number of held
- * read locks.
- *
- * @return a string identifying this lock, as well as its lock state
- */
- public String toString() {
- return super.toString() +
- "[Write locks = " + getWriteHoldCount() +
- ", Read locks = " + getReadLockCount() + "]";
- }
-}
diff --git a/src/build/bnd/scala-actors.bnd b/src/build/bnd/scala-actors.bnd
deleted file mode 100644
index 69885fc2bf..0000000000
--- a/src/build/bnd/scala-actors.bnd
+++ /dev/null
@@ -1,7 +0,0 @@
-Bundle-Name: Scala Actors
-Bundle-SymbolicName: org.scala-lang.scala-actors
-ver: @VERSION@
-Bundle-Version: ${ver}
-Export-Package: *;version=${ver}
-Import-Package: scala.*;version="${range;[==,=+);${ver}}",*
-Bundle-RequiredExecutionEnvironment: JavaSE-1.6, JavaSE-1.7
diff --git a/src/build/bnd/scala-continuations-library.bnd b/src/build/bnd/scala-continuations-library.bnd
deleted file mode 100644
index b36718cc5b..0000000000
--- a/src/build/bnd/scala-continuations-library.bnd
+++ /dev/null
@@ -1,7 +0,0 @@
-Bundle-Name: Scala Delimited Continuations Library
-Bundle-SymbolicName: org.scala-lang.plugins.scala-continuations-library
-ver: @CONTINUATIONS_LIBRARY_VERSION@
-Bundle-Version: ${ver}
-Export-Package: *;version=${ver}
-Import-Package: scala.*;version="${range;[==,=+);@VERSION@}",*
-Bundle-RequiredExecutionEnvironment: JavaSE-1.6, JavaSE-1.7
diff --git a/src/build/bnd/scala-continuations-plugin.bnd b/src/build/bnd/scala-continuations-plugin.bnd
deleted file mode 100644
index 2f2464b452..0000000000
--- a/src/build/bnd/scala-continuations-plugin.bnd
+++ /dev/null
@@ -1,7 +0,0 @@
-Bundle-Name: Scala Delimited Continuations Compiler Plugin
-Bundle-SymbolicName: org.scala-lang.plugins.scala-continuations-plugin
-ver: @CONTINUATIONS_PLUGIN_VERSION@
-Bundle-Version: ${ver}
-Export-Package: *;version=${ver}
-Import-Package: scala.*;version="${range;[==,=+);@VERSION@}",*
-Bundle-RequiredExecutionEnvironment: JavaSE-1.6, JavaSE-1.7
diff --git a/src/build/dbuild-meta-json-gen.scala b/src/build/dbuild-meta-json-gen.scala
index d1d4c12b3f..f967fffdd0 100644
--- a/src/build/dbuild-meta-json-gen.scala
+++ b/src/build/dbuild-meta-json-gen.scala
@@ -1,13 +1,19 @@
-// use this script to generate dbuild-meta.json
-// make sure the version is specified correctly,
-// update the dependency structure and
-// check out distributed-build and run `sbt console`:
-// TODO: also generate build.xml and eclipse config from a similar data-structure
+// Use this script to generate dbuild-meta.json
-import distributed.project.model._
+// To generate the file:
+// - check out https://github.com/typesafehub/dbuild
+// - run `sbt metadata/console`
+// - paste the code below
+
+// The `version` field is required for the ProjMeta data structure. However, dbuild will
+// overwrite the version specified here with the version number found in the build.number
+// file, so the actual value doesn't matter, see ScalaBuildSystem:
+// https://github.com/typesafehub/dbuild/blob/25b087759cc52876712c594ea4172148beea1310/support/src/main/scala/com/typesafe/dbuild/support/scala/ScalaBuildSystem.scala#L351
+
+import com.typesafe.dbuild.model._
val meta =
- ExtractedBuildMeta("2.11.0", Seq(
+ ProjMeta(version = "2.12.0", projects = Seq(
Project("scala-library", "org.scala-lang",
Seq(ProjectRef("scala-library", "org.scala-lang")),
Seq.empty), // TODO: forkjoin
@@ -19,7 +25,6 @@ val meta =
Seq(ProjectRef("scala-reflect", "org.scala-lang"),
ProjectRef("scala-xml", "org.scala-lang.modules"),
ProjectRef("scala-parser-combinators", "org.scala-lang.modules")
- // asm
)),
// Project("scala-repl", "org.scala-lang",
@@ -30,10 +35,6 @@ val meta =
// Seq(ProjectRef("scala-interactive", "org.scala-lang")),
// Seq(ProjectRef("scala-compiler", "org.scala-lang"), ProjectRef("scaladoc", "org.scala-lang"))),
- Project("scala-actors", "org.scala-lang",
- Seq(ProjectRef("scala-actors", "org.scala-lang")),
- Seq(ProjectRef("scala-library", "org.scala-lang"))),
-
// Project("scaladoc", "org.scala-lang",
// Seq(ProjectRef("scaladoc", "org.scala-lang")),
// Seq(ProjectRef("scala-compiler", "org.scala-lang"),ProjectRef("scala-partest", "org.scala-lang"), ProjectRef("scala-xml", "org.scala-lang"), ProjectRef("scala-parser-combinators", "org.scala-lang"))),
@@ -44,4 +45,4 @@ val meta =
))
-println(Utils.writeValue(meta))
+println(Utils.writeValueFormatted(meta))
diff --git a/src/build/maven/scala-actors-pom.xml b/src/build/maven/scala-actors-pom.xml
deleted file mode 100644
index a0ebcecad1..0000000000
--- a/src/build/maven/scala-actors-pom.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-<?xml version="1.0"?>
-<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>org.scala-lang</groupId>
- <artifactId>scala-actors</artifactId>
- <packaging>jar</packaging>
- <version>@VERSION@</version>
- <name>Scala Actors library</name>
- <description>Deprecated Actors Library for Scala</description>
- <url>http://www.scala-lang.org/</url>
- <inceptionYear>2006</inceptionYear>
- <organization>
- <name>LAMP/EPFL</name>
- <url>http://lamp.epfl.ch/</url>
- </organization>
- <licenses>
- <license>
- <name>BSD 3-Clause</name>
- <url>http://www.scala-lang.org/license.html</url>
- <distribution>repo</distribution>
- </license>
- </licenses>
- <scm>
- <connection>scm:git:git://github.com/scala/scala.git</connection>
- <url>https://github.com/scala/scala.git</url>
- </scm>
- <issueManagement>
- <system>JIRA</system>
- <url>https://issues.scala-lang.org/</url>
- </issueManagement>
- <properties>
- <info.apiURL>http://www.scala-lang.org/api/@VERSION@/</info.apiURL>
- </properties>
- <dependencies>
- <dependency>
- <groupId>org.scala-lang</groupId>
- <artifactId>scala-library</artifactId>
- <version>@VERSION@</version>
- </dependency>
- </dependencies>
- <developers>
- <developer>
- <id>lamp</id>
- <name>EPFL LAMP</name>
- </developer>
- <developer>
- <id>Typesafe</id>
- <name>Typesafe, Inc.</name>
- </developer>
- </developers>
-</project>
diff --git a/src/build/maven/scala-dist-pom.xml b/src/build/maven/scala-dist-pom.xml
index 9477e14285..1f6b6710ac 100644
--- a/src/build/maven/scala-dist-pom.xml
+++ b/src/build/maven/scala-dist-pom.xml
@@ -44,12 +44,6 @@
<artifactId>scalap</artifactId>
<version>@VERSION@</version>
</dependency>
- <dependency>
- <groupId>org.scala-lang.plugins</groupId>
- <!-- plugins are fully cross-versioned. But, we don't publish with 2.11.0-SNAPSHOT, instead use full version of the last non-snapshot version -->
- <artifactId>scala-continuations-plugin_@SCALA_FULL_VERSION@</artifactId>
- <version>@CONTINUATIONS_PLUGIN_VERSION@</version>
- </dependency>
<!-- duplicated from scala-compiler, where it's optional,
so that resolving scala-dist's transitive dependencies does not include jline,
even though we need to include it in the dist, but macros depending on the compiler
diff --git a/src/build/maven/scala-library-all-pom.xml b/src/build/maven/scala-library-all-pom.xml
index 3fcf207559..074c067742 100644
--- a/src/build/maven/scala-library-all-pom.xml
+++ b/src/build/maven/scala-library-all-pom.xml
@@ -49,31 +49,11 @@
<artifactId>scala-parser-combinators_@SCALA_BINARY_VERSION@</artifactId>
<version>@PARSER_COMBINATORS_VERSION@</version>
</dependency>
- <!--
- the continuations plugin is a dependency of scala-dist, as scala-library-all should be
- a drop-in replacement for scala-library, and as such should not (indirectly)
- depend on plugins/the compiler.
- -->
- <dependency>
- <groupId>org.scala-lang.plugins</groupId>
- <artifactId>scala-continuations-library_@SCALA_BINARY_VERSION@</artifactId>
- <version>@CONTINUATIONS_LIBRARY_VERSION@</version>
- </dependency>
<dependency>
<groupId>org.scala-lang.modules</groupId>
<artifactId>scala-swing_@SCALA_BINARY_VERSION@</artifactId>
<version>@SCALA_SWING_VERSION@</version>
</dependency>
- <dependency>
- <groupId>com.typesafe.akka</groupId>
- <artifactId>akka-actor_@SCALA_BINARY_VERSION@</artifactId>
- <version>@AKKA_ACTOR_VERSION@</version>
- </dependency>
- <dependency>
- <groupId>org.scala-lang</groupId>
- <artifactId>scala-actors-migration_@SCALA_BINARY_VERSION@</artifactId>
- <version>@ACTORS_MIGRATION_VERSION@</version>
- </dependency>
</dependencies>
<developers>
<developer>
diff --git a/src/compiler/scala/tools/cmd/Property.scala b/src/compiler/scala/tools/cmd/Property.scala
index b1d951a5c4..e6262a7e40 100644
--- a/src/compiler/scala/tools/cmd/Property.scala
+++ b/src/compiler/scala/tools/cmd/Property.scala
@@ -9,6 +9,7 @@ package cmd
import nsc.io._
import java.util.Properties
import java.io.FileInputStream
+import scala.sys.SystemProperties
/** Contains logic for translating a property key/value pair into
* equivalent command line arguments. The default settings will
@@ -58,7 +59,7 @@ trait Property extends Reference {
returning(new Properties)(_ load new FileInputStream(file.path))
def systemPropertiesToOptions: List[String] =
- propertiesToOptions(System.getProperties)
+ propertiesToOptions(new SystemProperties().toList)
def propertiesToOptions(file: File): List[String] =
propertiesToOptions(loadProperties(file))
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 3469726455..778f2fed59 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -1378,8 +1378,11 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
settings.userSetSettings filter (_.isDeprecated) foreach { s =>
currentRun.reporting.deprecationWarning(NoPosition, s.name + " is deprecated: " + s.deprecationMessage.get)
}
- if (settings.target.value.contains("jvm-1.5"))
- currentRun.reporting.deprecationWarning(NoPosition, settings.target.name + ":" + settings.target.value + " is deprecated: use target for Java 1.6 or above.")
+ val supportedTarget = "jvm-1.8"
+ if (settings.target.value != supportedTarget) {
+ currentRun.reporting.deprecationWarning(NoPosition, settings.target.name + ":" + settings.target.value + " is deprecated and has no effect, setting to " + supportedTarget)
+ settings.target.value = supportedTarget
+ }
}
/* An iterator returning all the units being compiled in this run */
diff --git a/src/compiler/scala/tools/nsc/ast/DocComments.scala b/src/compiler/scala/tools/nsc/ast/DocComments.scala
index 6442ef2d54..c70690e697 100755
--- a/src/compiler/scala/tools/nsc/ast/DocComments.scala
+++ b/src/compiler/scala/tools/nsc/ast/DocComments.scala
@@ -129,25 +129,6 @@ trait DocComments { self: Global =>
getDocComment(sym) map getUseCases getOrElse List()
}
- private val wikiReplacements = List(
- ("""(\n\s*\*?)(\s*\n)""" .r, """$1 <p>$2"""),
- ("""<([^\w/])""" .r, """&lt;$1"""),
- ("""([^\w/])>""" .r, """$1&gt;"""),
- ("""\{\{\{(.*(?:\n.*)*)\}\}\}""".r, """<pre>$1</pre>"""),
- ("""`([^`]*)`""" .r, """<code>$1</code>"""),
- ("""__([^_]*)__""" .r, """<u>$1</u>"""),
- ("""''([^']*)''""" .r, """<i>$1</i>"""),
- ("""'''([^']*)'''""" .r, """<b>$1</b>"""),
- ("""\^([^^]*)\^""" .r, """<sup>$1</sup>"""),
- (""",,([^,]*),,""" .r, """<sub>$1</sub>"""))
-
- /** Returns just the wiki expansion (this would correspond to
- * a comment in the input format of the JavaDoc tool, modulo differences
- * in tags.)
- */
- def expandWiki(str: String): String =
- (str /: wikiReplacements) { (str1, regexRepl) => regexRepl._1 replaceAllIn(str1, regexRepl._2) }
-
private def getDocComment(sym: Symbol): Option[DocComment] =
mapFind(sym :: allInheritedOverriddenSymbols(sym))(docComments get _)
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index 4f195c2985..b76fb3d823 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -665,6 +665,15 @@ self =>
}
def isLiteral = isLiteralToken(in.token)
+ def isSimpleExprIntroToken(token: Token): Boolean = isLiteralToken(token) || (token match {
+ case IDENTIFIER | BACKQUOTED_IDENT |
+ THIS | SUPER | NEW | USCORE |
+ LPAREN | LBRACE | XMLSTART => true
+ case _ => false
+ })
+
+ def isSimpleExprIntro: Boolean = isExprIntroToken(in.token)
+
def isExprIntroToken(token: Token): Boolean = isLiteralToken(token) || (token match {
case IDENTIFIER | BACKQUOTED_IDENT |
THIS | SUPER | IF | FOR | NEW | USCORE | TRY | WHILE |
@@ -1565,11 +1574,14 @@ self =>
def prefixExpr(): Tree = {
if (isUnaryOp) {
atPos(in.offset) {
- val name = nme.toUnaryName(rawIdent().toTermName)
- if (name == nme.UNARY_- && isNumericLit)
- simpleExprRest(literal(isNegated = true), canApply = true)
- else
- Select(stripParens(simpleExpr()), name)
+ if (lookingAhead(isSimpleExprIntro)) {
+ val uname = nme.toUnaryName(rawIdent().toTermName)
+ if (uname == nme.UNARY_- && isNumericLit)
+ simpleExprRest(literal(isNegated = true), canApply = true)
+ else
+ Select(stripParens(simpleExpr()), uname)
+ }
+ else simpleExpr()
}
}
else simpleExpr()
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index 3e23291e92..01eff71057 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -1145,7 +1145,7 @@ abstract class GenICode extends SubComponent {
// a package here, check if there's a package object.
val sym = (
if (!tree.symbol.isPackageClass) tree.symbol
- else tree.symbol.info.member(nme.PACKAGE) match {
+ else tree.symbol.info.packageObject match {
case NoSymbol => abort("Cannot use package as value: " + tree)
case s =>
devWarning(s"Found ${tree.symbol} where a package object is required. Converting to ${s.moduleClass}")
@@ -1502,7 +1502,7 @@ abstract class GenICode extends SubComponent {
if (!settings.optimise) {
if (l.tpe <:< BoxedNumberClass.tpe) {
if (r.tpe <:< BoxedNumberClass.tpe) platform.externalEqualsNumNum
- else if (r.tpe <:< BoxedCharacterClass.tpe) platform.externalEqualsNumObject // will be externalEqualsNumChar in 2.12, SI-9030
+ else if (r.tpe <:< BoxedCharacterClass.tpe) platform.externalEqualsNumChar
else platform.externalEqualsNumObject
} else platform.externalEquals
} else {
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
index 40ba0c010b..c3f71969f6 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
@@ -842,7 +842,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
* loading another throwable first).
*
* New (http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.10.1)
- * - Requires consistent stack map frames. GenBCode generates stack frames if -target:jvm-1.6
+ * - Requires consistent stack map frames. GenBCode always generates stack frames.
* or higher.
* - In practice: the ASM library computes stack map frames for us (ClassWriter). Emitting
* correct frames after an ATHROW is probably complex, so ASM uses the following strategy:
@@ -921,7 +921,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
def genLoadModule(tree: Tree): BType = {
val module = (
if (!tree.symbol.isPackageClass) tree.symbol
- else tree.symbol.info.member(nme.PACKAGE) match {
+ else tree.symbol.info.packageObject match {
case NoSymbol => abort(s"SI-5604: Cannot use package as value: $tree")
case s => abort(s"SI-5604: found package class where package object expected: $tree")
}
@@ -1231,7 +1231,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
val equalsMethod: Symbol = {
if (l.tpe <:< BoxedNumberClass.tpe) {
if (r.tpe <:< BoxedNumberClass.tpe) platform.externalEqualsNumNum
- else if (r.tpe <:< BoxedCharacterClass.tpe) platform.externalEqualsNumObject // will be externalEqualsNumChar in 2.12, SI-9030
+ else if (r.tpe <:< BoxedCharacterClass.tpe) platform.externalEqualsNumChar
else platform.externalEqualsNumObject
} else platform.externalEquals
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala
index 8f2a17a2bf..a25f5cad63 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala
@@ -28,9 +28,6 @@ abstract class BCodeIdiomatic extends SubComponent {
import coreBTypes._
val classfileVersion: Int = settings.target.value match {
- case "jvm-1.5" => asm.Opcodes.V1_5
- case "jvm-1.6" => asm.Opcodes.V1_6
- case "jvm-1.7" => asm.Opcodes.V1_7
case "jvm-1.8" => asm.Opcodes.V1_8
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
index 71686fd9d7..ccad50616c 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
@@ -441,9 +441,6 @@ abstract class GenASM extends SubComponent with BytecodeWriters { self =>
// -----------------------------------------------------------------------------------------
private val classfileVersion: Int = settings.target.value match {
- case "jvm-1.5" => asm.Opcodes.V1_5
- case "jvm-1.6" => asm.Opcodes.V1_6
- case "jvm-1.7" => asm.Opcodes.V1_7
case "jvm-1.8" => asm.Opcodes.V1_8
}
diff --git a/src/compiler/scala/tools/nsc/settings/AbsScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/AbsScalaSettings.scala
index 6b339b2a6d..8386722b63 100644
--- a/src/compiler/scala/tools/nsc/settings/AbsScalaSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/AbsScalaSettings.scala
@@ -31,6 +31,7 @@ trait AbsScalaSettings {
def BooleanSetting(name: String, descr: String): BooleanSetting
def ChoiceSetting(name: String, helpArg: String, descr: String, choices: List[String], default: String): ChoiceSetting
+ def ChoiceSettingForcedDefault(name: String, helpArg: String, descr: String, choices: List[String], default: String): ChoiceSetting
def IntSetting(name: String, descr: String, default: Int, range: Option[(Int, Int)], parser: String => Option[Int]): IntSetting
def MultiStringSetting(name: String, helpArg: String, descr: String): MultiStringSetting
def MultiChoiceSetting[E <: MultiChoiceEnumeration](name: String, helpArg: String, descr: String, domain: E, default: Option[List[String]]): MultiChoiceSetting[E]
diff --git a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala
index b4987e1240..9cc8faf8c2 100644
--- a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala
@@ -221,6 +221,13 @@ class MutableSettings(val errorFn: String => Unit)
def BooleanSetting(name: String, descr: String) = add(new BooleanSetting(name, descr))
def ChoiceSetting(name: String, helpArg: String, descr: String, choices: List[String], default: String) =
add(new ChoiceSetting(name, helpArg, descr, choices, default))
+ def ChoiceSettingForcedDefault(name: String, helpArg: String, descr: String, choices: List[String], default: String) =
+ ChoiceSetting(name, helpArg, descr, choices, default).withPostSetHook(sett =>
+ if (sett.value != default) {
+ sett.withDeprecationMessage(s"${name}:${sett.value} is deprecated, forcing use of $default")
+ sett.value = default
+ }
+ )
def IntSetting(name: String, descr: String, default: Int, range: Option[(Int, Int)], parser: String => Option[Int]) =
add(new IntSetting(name, descr, default, range, parser))
def MultiStringSetting(name: String, arg: String, descr: String) = add(new MultiStringSetting(name, arg, descr))
diff --git a/src/compiler/scala/tools/nsc/settings/ScalaVersion.scala b/src/compiler/scala/tools/nsc/settings/ScalaVersion.scala
index 43bdad5882..7e67b7bec6 100644
--- a/src/compiler/scala/tools/nsc/settings/ScalaVersion.scala
+++ b/src/compiler/scala/tools/nsc/settings/ScalaVersion.scala
@@ -68,45 +68,39 @@ case object AnyScalaVersion extends ScalaVersion {
* Factory methods for producing ScalaVersions
*/
object ScalaVersion {
- private val dot = "\\."
- private val dash = "\\-"
- private def not(s:String) = s"[^${s}]"
- private val R = s"((${not(dot)}*)(${dot}(${not(dot)}*)(${dot}(${not(dash)}*)(${dash}(.*))?)?)?)".r
-
- def apply(versionString : String, errorHandler: String => Unit): ScalaVersion = {
- def errorAndValue() = {
- errorHandler(
- s"There was a problem parsing ${versionString}. " +
- "Versions should be in the form major[.minor[.revision]] " +
- "where each part is a positive number, as in 2.10.1. " +
- "The minor and revision parts are optional."
- )
- AnyScalaVersion
- }
+ private val dot = """\."""
+ private val dash = "-"
+ private val vchar = """\d""" //"[^-+.]"
+ private val vpat = s"(?s)($vchar+)(?:$dot($vchar+)(?:$dot($vchar+)(?:$dash(.*))?)?)?".r
+ private val rcpat = """(?i)rc(\d*)""".r
+ private val mspat = """(?i)m(\d*)""".r
+
+ def apply(versionString: String, errorHandler: String => Unit): ScalaVersion = {
+ def error() = errorHandler(
+ s"There was a problem parsing ${versionString}. " +
+ "Versions should be in the form major[.minor[.revision]] " +
+ "where each part is a positive number, as in 2.10.1. " +
+ "The minor and revision parts are optional."
+ )
def toInt(s: String) = s match {
case null | "" => 0
- case _ => s.toInt
+ case _ => s.toInt
}
- def isInt(s: String) = util.Try(toInt(s)).isSuccess
-
def toBuild(s: String) = s match {
case null | "FINAL" => Final
- case s if (s.toUpperCase.startsWith("RC") && isInt(s.substring(2))) => RC(toInt(s.substring(2)))
- case s if (s.toUpperCase.startsWith("M") && isInt(s.substring(1))) => Milestone(toInt(s.substring(1)))
- case _ => Development(s)
+ case rcpat(i) => RC(toInt(i))
+ case mspat(i) => Milestone(toInt(i))
+ case _ /* | "" */ => Development(s)
}
- try versionString match {
+ versionString match {
case "none" => NoScalaVersion
- case "any" => AnyScalaVersion
- case R(_, majorS, _, minorS, _, revS, _, buildS) =>
+ case "any" => AnyScalaVersion
+ case vpat(majorS, minorS, revS, buildS) =>
SpecificScalaVersion(toInt(majorS), toInt(minorS), toInt(revS), toBuild(buildS))
- case _ =>
- errorAndValue()
- } catch {
- case e: NumberFormatException => errorAndValue()
+ case _ => error() ; AnyScalaVersion
}
}
diff --git a/src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala
index d42c0dd730..f197a4930d 100644
--- a/src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala
@@ -38,8 +38,8 @@ trait StandardScalaSettings {
val nowarn = BooleanSetting ("-nowarn", "Generate no warnings.")
val optimise: BooleanSetting // depends on post hook which mutates other settings
val print = BooleanSetting ("-print", "Print program with Scala-specific features removed.")
- val target = ChoiceSetting ("-target", "target", "Target platform for object files. All JVM 1.5 targets are deprecated.",
- List("jvm-1.5", "jvm-1.6", "jvm-1.7", "jvm-1.8"), "jvm-1.6")
+ val target = ChoiceSettingForcedDefault ("-target", "target", "Target platform for object files. All JVM 1.5 - 1.7 targets are deprecated.",
+ List("jvm-1.5", "jvm-1.6", "jvm-1.7", "jvm-1.8"), "jvm-1.8")
val unchecked = BooleanSetting ("-unchecked", "Enable additional warnings where generated code depends on assumptions.")
val uniqid = BooleanSetting ("-uniqid", "Uniquely tag all identifiers in debugging output.")
val usejavacp = BooleanSetting ("-usejavacp", "Utilize the java.class.path in classpath resolution.")
diff --git a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala
index 5a7f6c52da..ddf003bb98 100644
--- a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala
+++ b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala
@@ -18,7 +18,7 @@ import scala.collection.mutable.LinkedHashMap
*
* From a lambda, Delambdafy will create:
*
- * Under -target:jvm-1.7 and below:
+ * Under GenASM
*
* 1) a new top level class that
a) has fields and a constructor taking the captured environment (including possibly the "this"
@@ -27,7 +27,7 @@ import scala.collection.mutable.LinkedHashMap
* c) if needed a bridge method for the apply method
* 2) an instantiation of the newly created class which replaces the lambda
*
- * Under -target:jvm-1.8 with GenBCode:
+ * Under GenBCode:
*
* 1) An application of the captured arguments to a fictional symbol representing the lambda factory.
* This will be translated by the backed into an invokedynamic using a bootstrap method in JDK8's `LambdaMetaFactory`.
@@ -571,10 +571,7 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre
// The functional interface that can be used to adapt the lambda target method `target` to the
// given function type. Returns `NoSymbol` if the compiler settings are unsuitable.
private def java8CompatFunctionalInterface(target: Symbol, functionType: Type): (Symbol, Boolean) = {
- val canUseLambdaMetafactory: Boolean = {
- val isTarget18 = settings.target.value.contains("jvm-1.8")
- settings.isBCodeActive && isTarget18
- }
+ val canUseLambdaMetafactory = settings.isBCodeActive
val sym = functionType.typeSymbol
val pack = currentRun.runDefinitions.Scala_Java8_CompatPackage
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index a04625c9c5..833f25537c 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -341,8 +341,8 @@ abstract class Erasure extends AddInterfaces
buf append (if (restpe.typeSymbol == UnitClass || sym0.isConstructor) VOID_TAG.toString else jsig(restpe))
buf.toString
- case RefinedType(parent :: _, decls) =>
- boxedSig(parent)
+ case RefinedType(parents, decls) =>
+ boxedSig(intersectionDominator(parents))
case ClassInfoType(parents, _, _) =>
superSig(parents)
case AnnotatedType(_, atp) =>
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
index 540de2cfe1..f12f6c4e18 100644
--- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
@@ -446,8 +446,10 @@ abstract class ExplicitOuter extends InfoTransform
//
// See SI-6552 for an example of why `sym.owner.enclMethod hasAnnotation ScalaInlineClass`
// is not suitable; if we make a method-local class non-private, it mangles outer pointer names.
- if (currentClass != sym.owner ||
- (closestEnclMethod(currentOwner) hasAnnotation ScalaInlineClass))
+ def enclMethodIsInline = closestEnclMethod(currentOwner) hasAnnotation ScalaInlineClass
+ // SI-8710 The extension method condition reflects our knowledge that a call to `new Meter(12).privateMethod`
+ // with later be rewritten (in erasure) to `Meter.privateMethod$extension(12)`.
+ if ((currentClass != sym.owner || enclMethodIsInline) && !sym.isMethodWithExtension)
sym.makeNotPrivate(sym.owner)
val qsym = qual.tpe.widen.typeSymbol
diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
index 116047a2ad..6349fc3fb9 100644
--- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
@@ -208,7 +208,7 @@ abstract class ExtensionMethods extends Transform with TypingTransformers {
def makeExtensionMethodSymbol = {
val extensionName = extensionNames(origMeth).head.toTermName
val extensionMeth = (
- companion.moduleClass.newMethod(extensionName, tree.pos.focus, origMeth.flags & ~OVERRIDE & ~PROTECTED & ~LOCAL | FINAL)
+ companion.moduleClass.newMethod(extensionName, tree.pos.focus, origMeth.flags & ~OVERRIDE & ~PROTECTED & ~PRIVATE & ~LOCAL | FINAL)
setAnnotations origMeth.annotations
)
origMeth.removeAnnotation(TailrecClass) // it's on the extension method, now.
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index b310e6c3a1..65316e4f00 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -237,7 +237,7 @@ abstract class UnCurry extends InfoTransform
def canUseDelamdafyMethod = (
(inConstructorFlag == 0) // Avoiding synthesizing code prone to SI-6666, SI-8363 by using old-style lambda translation
- && (!isSpecialized || (settings.isBCodeActive && settings.target.value == "jvm-1.8")) // DelambdafyTransformer currently only emits generic FunctionN-s, use the old style in the meantime
+ && (!isSpecialized || settings.isBCodeActive) // DelambdafyTransformer currently only emits generic FunctionN-s, use the old style in the meantime
)
if (inlineFunctionExpansion || !canUseDelamdafyMethod) {
val parents = addSerializable(abstractFunctionForFunctionType(fun.tpe))
diff --git a/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala b/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala
index 56ed0ee16c..2f4771e9d4 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala
@@ -75,7 +75,7 @@ abstract class ConstantFolder {
case nme.AND => Constant(x.booleanValue & y.booleanValue)
case nme.EQ => Constant(x.booleanValue == y.booleanValue)
case nme.NE => Constant(x.booleanValue != y.booleanValue)
- case _ => null
+ case _ => null
}
private def foldSubrangeOp(op: Name, x: Constant, y: Constant): Constant = op match {
case nme.OR => Constant(x.intValue | y.intValue)
@@ -95,14 +95,20 @@ abstract class ConstantFolder {
case nme.MUL => Constant(x.intValue * y.intValue)
case nme.DIV => Constant(x.intValue / y.intValue)
case nme.MOD => Constant(x.intValue % y.intValue)
- case _ => null
+ case _ => null
}
private def foldLongOp(op: Name, x: Constant, y: Constant): Constant = op match {
case nme.OR => Constant(x.longValue | y.longValue)
case nme.XOR => Constant(x.longValue ^ y.longValue)
case nme.AND => Constant(x.longValue & y.longValue)
- case nme.LSL => Constant(x.longValue << y.longValue)
+ case nme.LSL if x.tag <= IntTag
+ => Constant(x.intValue << y.longValue)
+ case nme.LSL => Constant(x.longValue << y.longValue)
+ case nme.LSR if x.tag <= IntTag
+ => Constant(x.intValue >>> y.longValue)
case nme.LSR => Constant(x.longValue >>> y.longValue)
+ case nme.ASR if x.tag <= IntTag
+ => Constant(x.intValue >> y.longValue)
case nme.ASR => Constant(x.longValue >> y.longValue)
case nme.EQ => Constant(x.longValue == y.longValue)
case nme.NE => Constant(x.longValue != y.longValue)
@@ -115,7 +121,7 @@ abstract class ConstantFolder {
case nme.MUL => Constant(x.longValue * y.longValue)
case nme.DIV => Constant(x.longValue / y.longValue)
case nme.MOD => Constant(x.longValue % y.longValue)
- case _ => null
+ case _ => null
}
private def foldFloatOp(op: Name, x: Constant, y: Constant): Constant = op match {
case nme.EQ => Constant(x.floatValue == y.floatValue)
@@ -129,7 +135,7 @@ abstract class ConstantFolder {
case nme.MUL => Constant(x.floatValue * y.floatValue)
case nme.DIV => Constant(x.floatValue / y.floatValue)
case nme.MOD => Constant(x.floatValue % y.floatValue)
- case _ => null
+ case _ => null
}
private def foldDoubleOp(op: Name, x: Constant, y: Constant): Constant = op match {
case nme.EQ => Constant(x.doubleValue == y.doubleValue)
@@ -143,7 +149,7 @@ abstract class ConstantFolder {
case nme.MUL => Constant(x.doubleValue * y.doubleValue)
case nme.DIV => Constant(x.doubleValue / y.doubleValue)
case nme.MOD => Constant(x.doubleValue % y.doubleValue)
- case _ => null
+ case _ => null
}
private def foldBinop(op: Name, x: Constant, y: Constant): Constant = {
@@ -162,7 +168,7 @@ abstract class ConstantFolder {
case _ => null
}
catch {
- case ex: ArithmeticException => null
+ case _: ArithmeticException => null
}
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index 542f58795a..7c931600e5 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -809,12 +809,8 @@ trait Contexts { self: Analyzer =>
private def collectImplicitImports(imp: ImportInfo): List[ImplicitInfo] = {
val qual = imp.qual
- val pre =
- if (qual.tpe.typeSymbol.isPackageClass)
- // SI-6225 important if the imported symbol is inherited by the the package object.
- singleType(qual.tpe, qual.tpe member nme.PACKAGE)
- else
- qual.tpe
+ val qualSym = qual.tpe.typeSymbol
+ val pre = qual.tpe
def collect(sels: List[ImportSelector]): List[ImplicitInfo] = sels match {
case List() =>
List()
@@ -885,7 +881,8 @@ trait Contexts { self: Analyzer =>
Some(collectImplicitImports(imports.head))
} else if (owner.isPackageClass) {
// the corresponding package object may contain implicit members.
- Some(collectImplicits(owner.tpe.implicitMembers, owner.tpe))
+ val pre = owner.packageObject.typeOfThis
+ Some(collectImplicits(pre.implicitMembers, pre))
} else Some(Nil)
}
@@ -955,52 +952,18 @@ trait Contexts { self: Analyzer =>
private def importedAccessibleSymbol(imp: ImportInfo, name: Name, requireExplicit: Boolean): Symbol =
imp.importedSymbol(name, requireExplicit) filter (s => isAccessible(s, imp.qual.tpe, superAccess = false))
- /** Is `sym` defined in package object of package `pkg`?
- * Since sym may be defined in some parent of the package object,
- * we cannot inspect its owner only; we have to go through the
- * info of the package object. However to avoid cycles we'll check
- * what other ways we can before pushing that way.
- */
- def isInPackageObject(sym: Symbol, pkg: Symbol): Boolean = {
- def uninitialized(what: String) = {
- log(s"Cannot look for $sym in package object of $pkg; $what is not initialized.")
- false
- }
- def pkgClass = if (pkg.isTerm) pkg.moduleClass else pkg
- def matchesInfo = (
- // need to be careful here to not get a cyclic reference during bootstrap
- if (pkg.isInitialized) {
- val module = pkg.info member nme.PACKAGEkw
- if (module.isInitialized)
- module.info.member(sym.name).alternatives contains sym
- else
- uninitialized("" + module)
- }
- else uninitialized("" + pkg)
- )
- def inPackageObject(sym: Symbol) = (
- // To be in the package object, one of these must be true:
- // 1) sym.owner is a package object class, and sym.owner.owner is the package class for `pkg`
- // 2) sym.owner is inherited by the correct package object class
- // We try to establish 1) by inspecting the owners directly, and then we try
- // to rule out 2), and only if both those fail do we resort to looking in the info.
- !sym.hasPackageFlag && sym.owner.exists && (
- if (sym.owner.isPackageObjectClass)
- sym.owner.owner == pkgClass
- else
- !sym.owner.isPackageClass && matchesInfo
- )
- )
+ private def requiresQualifier(s: Symbol) = (
+ s.owner.isClass
+ && !s.owner.isPackageClass
+ && !s.isTypeParameterOrSkolem
+ && !s.isExistentiallyBound
+ )
- // An overloaded symbol might not have the expected owner!
- // The alternatives must be inspected directly.
- pkgClass.isPackageClass && (
- if (sym.isOverloaded)
- sym.alternatives forall (isInPackageObject(_, pkg))
- else
- inPackageObject(sym)
- )
- }
+ /** Must `sym` defined in package object of package `pkg`, if
+ * it selected from a prefix with `pkg` as its type symbol?
+ */
+ def isInPackageObject(sym: Symbol, pkg: Symbol): Boolean =
+ pkg.isPackage && sym.owner != pkg && requiresQualifier(sym)
def isNameInScope(name: Name) = lookupSymbol(name, _ => true).isSuccess
@@ -1036,11 +999,6 @@ trait Contexts { self: Analyzer =>
|| unit.exists && s.sourceFile != unit.source.file
)
)
- def requiresQualifier(s: Symbol) = (
- s.owner.isClass
- && !s.owner.isPackageClass
- && !s.isTypeParameterOrSkolem
- )
def lookupInPrefix(name: Name) = pre member name filter qualifies
def accessibleInPrefix(s: Symbol) = isAccessible(s, pre, superAccess = false)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index 80e06eb8fa..3274c86072 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -1012,15 +1012,12 @@ trait Implicits {
}
case None =>
if (pre.isStable && !pre.typeSymbol.isExistentiallyBound) {
- val companion = companionSymbolOf(sym, context)
- companion.moduleClass match {
- case mc: ModuleClassSymbol =>
- val infos =
- for (im <- mc.implicitMembers.toList) yield new ImplicitInfo(im.name, singleType(pre, companion), im)
- if (infos.nonEmpty)
- infoMap += (sym -> infos)
- case _ =>
- }
+ val pre1 =
+ if (sym.isPackageClass) sym.packageObject.typeOfThis
+ else singleType(pre, companionSymbolOf(sym, context))
+ val infos = pre1.implicitMembers.iterator.map(mem => new ImplicitInfo(mem.name, pre1, mem)).toList
+ if (infos.nonEmpty)
+ infoMap += (sym -> infos)
}
val bts = tp.baseTypeSeq
var i = 1
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index ea0a9bb243..a4c794e8cf 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -1446,7 +1446,7 @@ trait Infer extends Checkable {
log(s"Attaching AntiPolyType-carrying overloaded type to $sym")
// Multiple alternatives which are within bounds; spin up an
// overloaded type which carries an "AntiPolyType" as a prefix.
- val tparams = newAsSeenFromMap(pre, hd.owner) mapOver hd.typeParams
+ val tparams = new AsSeenFromMap(pre, hd.owner) mapOver hd.typeParams
val bounds = tparams map (_.tpeHK) // see e.g., #1236
val tpe = PolyType(tparams, OverloadedType(AntiPolyType(pre, bounds), alts))
finish(sym setInfo tpe, tpe)
diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
index 39cd610b1c..1bc5daac65 100644
--- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
@@ -9,6 +9,7 @@ package typechecker
import symtab.Flags._
import scala.collection.mutable
import scala.reflect.ClassTag
+import PartialFunction.{ cond => when }
/**
* @author Lukas Rytz
@@ -551,64 +552,73 @@ trait NamesDefaults { self: Analyzer =>
}
}
- /**
- * Removes name assignments from args. Additionally, returns an array mapping
- * argument indices from call-site-order to definition-site-order.
+ /** Removes name assignments from args. Additionally, returns an array mapping
+ * argument indices from call-site-order to definition-site-order.
*
- * Verifies that names are not specified twice, positional args don't appear
- * after named ones.
+ * Verifies that names are not specified twice, and positional args don't appear after named ones.
*/
def removeNames(typer: Typer)(args: List[Tree], params: List[Symbol]): (List[Tree], Array[Int]) = {
implicit val context0 = typer.context
- // maps indices from (order written by user) to (order of definition)
- val argPos = Array.fill(args.length)(-1)
- var positionalAllowed = true
- val namelessArgs = mapWithIndex(args) { (arg, argIndex) =>
- arg match {
- case arg @ AssignOrNamedArg(Ident(name), rhs) =>
- def matchesName(param: Symbol) = !param.isSynthetic && (
- (param.name == name) || (param.deprecatedParamName match {
- case Some(`name`) =>
- context0.deprecationWarning(arg.pos, param,
- s"the parameter name $name has been deprecated. Use ${param.name} instead.")
- true
- case _ => false
- })
- )
- val paramPos = params indexWhere matchesName
- if (paramPos == -1) {
- if (positionalAllowed) {
- argPos(argIndex) = argIndex
- // prevent isNamed from being true when calling doTypedApply recursively,
- // treat the arg as an assignment of type Unit
- Assign(arg.lhs, rhs) setPos arg.pos
- }
- else UnknownParameterNameNamesDefaultError(arg, name)
- }
- else if (argPos contains paramPos) {
+ def matchesName(param: Symbol, name: Name, argIndex: Int) = {
+ def warn(w: String) = context0.deprecationWarning(args(argIndex).pos, param, w)
+ def checkDeprecation(anonOK: Boolean) =
+ when (param.deprecatedParamName) {
+ case Some(`name`) => true
+ case Some(nme.NO_NAME) => anonOK
+ }
+ def checkName = {
+ val res = param.name == name
+ if (res && checkDeprecation(true)) warn(s"naming parameter $name has been deprecated.")
+ res
+ }
+ def checkAltName = {
+ val res = checkDeprecation(false)
+ if (res) warn(s"the parameter name $name has been deprecated. Use ${param.name} instead.")
+ res
+ }
+ !param.isSynthetic && (checkName || checkAltName)
+ }
+ // argPos maps indices from (order written by user) to (order of definition)
+ val argPos = Array.fill(args.length)(-1)
+ val namelessArgs = {
+ var positionalAllowed = true
+ def stripNamedArg(arg: AssignOrNamedArg, argIndex: Int): Tree = {
+ val AssignOrNamedArg(Ident(name), rhs) = arg
+ params indexWhere (p => matchesName(p, name, argIndex)) match {
+ case -1 if positionalAllowed =>
+ // prevent isNamed from being true when calling doTypedApply recursively,
+ // treat the arg as an assignment of type Unit
+ Assign(arg.lhs, rhs) setPos arg.pos
+ case -1 =>
+ UnknownParameterNameNamesDefaultError(arg, name)
+ case paramPos if argPos contains paramPos =>
val existingArgIndex = argPos.indexWhere(_ == paramPos)
- val otherName = args(paramPos) match {
- case AssignOrNamedArg(Ident(oName), rhs) if oName != name => Some(oName)
- case _ => None
+ val otherName = Some(args(paramPos)) collect {
+ case AssignOrNamedArg(Ident(oName), _) if oName != name => oName
}
DoubleParamNamesDefaultError(arg, name, existingArgIndex+1, otherName)
- } else if (isAmbiguousAssignment(typer, params(paramPos), arg))
+ case paramPos if isAmbiguousAssignment(typer, params(paramPos), arg) =>
AmbiguousReferenceInNamesDefaultError(arg, name)
- else {
- // if the named argument is on the original parameter
- // position, positional after named is allowed.
- if (argIndex != paramPos)
- positionalAllowed = false
- argPos(argIndex) = paramPos
+ case paramPos if paramPos != argIndex =>
+ positionalAllowed = false // named arg is not in original parameter order: require names after this
+ argPos(argIndex) = paramPos // fix up the arg position
rhs
- }
- case _ =>
- argPos(argIndex) = argIndex
- if (positionalAllowed) arg
- else PositionalAfterNamedNamesDefaultError(arg)
+ case _ => rhs
+ }
+ }
+ mapWithIndex(args) {
+ case (arg: AssignOrNamedArg, argIndex) =>
+ val t = stripNamedArg(arg, argIndex)
+ if (!t.isErroneous && argPos(argIndex) < 0) argPos(argIndex) = argIndex
+ t
+ case (arg, argIndex) =>
+ if (positionalAllowed) {
+ argPos(argIndex) = argIndex
+ arg
+ } else
+ PositionalAfterNamedNamesDefaultError(arg)
}
}
-
(namelessArgs, argPos)
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
index 966e8f1abe..d65d2092ad 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
@@ -87,24 +87,6 @@ trait SyntheticMethods extends ast.TreeDSL {
def accessors = clazz.caseFieldAccessors
val arity = accessors.size
- // If this is ProductN[T1, T2, ...], accessorLub is the lub of T1, T2, ..., .
- // !!! Hidden behind -Xexperimental due to bummer type inference bugs.
- // Refining from Iterator[Any] leads to types like
- //
- // Option[Int] { def productIterator: Iterator[String] }
- //
- // appearing legitimately, but this breaks invariant places
- // like Tags and Arrays which are not robust and infer things
- // which they shouldn't.
- val accessorLub = (
- if (settings.Xexperimental) {
- global.lub(accessors map (_.tpe.finalResultType)) match {
- case RefinedType(parents, decls) if !decls.isEmpty => intersectionType(parents)
- case tp => tp
- }
- }
- else AnyTpe
- )
def forwardToRuntime(method: Symbol): Tree =
forwardMethod(method, getMember(ScalaRunTimeModule, (method.name prepend "_")))(mkThis :: _)
@@ -125,8 +107,8 @@ trait SyntheticMethods extends ast.TreeDSL {
}
}
def productIteratorMethod = {
- createMethod(nme.productIterator, iteratorOfType(accessorLub))(_ =>
- gen.mkMethodCall(ScalaRunTimeModule, nme.typedProductIterator, List(accessorLub), List(mkThis))
+ createMethod(nme.productIterator, iteratorOfType(AnyTpe))(_ =>
+ gen.mkMethodCall(ScalaRunTimeModule, nme.typedProductIterator, List(AnyTpe), List(mkThis))
)
}
@@ -246,7 +228,7 @@ trait SyntheticMethods extends ast.TreeDSL {
List(
Product_productPrefix -> (() => constantNullary(nme.productPrefix, clazz.name.decode)),
Product_productArity -> (() => constantNullary(nme.productArity, arity)),
- Product_productElement -> (() => perElementMethod(nme.productElement, accessorLub)(mkThisSelect)),
+ Product_productElement -> (() => perElementMethod(nme.productElement, AnyTpe)(mkThisSelect)),
Product_iterator -> (() => productIteratorMethod),
Product_canEqual -> (() => canEqualMethod)
// This is disabled pending a reimplementation which doesn't add any
@@ -380,7 +362,14 @@ trait SyntheticMethods extends ast.TreeDSL {
for (ddef @ DefDef(_, _, _, _, _, _) <- templ.body ; if isRewrite(ddef.symbol)) {
val original = ddef.symbol
- val newAcc = deriveMethod(ddef.symbol, name => context.unit.freshTermName(name + "$")) { newAcc =>
+ val i = original.owner.caseFieldAccessors.indexOf(original)
+ def freshAccessorName = {
+ devWarning(s"Unable to find $original among case accessors of ${original.owner}: ${original.owner.caseFieldAccessors}")
+ context.unit.freshTermName(original.name + "$")
+ }
+ def nameSuffixedByParamIndex = original.name.append(nme.CASE_ACCESSOR + "$" + i).toTermName
+ val newName = if (i < 0) freshAccessorName else nameSuffixedByParamIndex
+ val newAcc = deriveMethod(ddef.symbol, name => newName) { newAcc =>
newAcc.makePublic
newAcc resetFlag (ACCESSOR | PARAMACCESSOR | OVERRIDE)
ddef.rhs.duplicate
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index b5129af9ec..2dfecbaea1 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -542,7 +542,11 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
}
val qual = typedQualifier { atPos(tree.pos.makeTransparent) {
tree match {
- case Ident(_) => Ident(rootMirror.getPackageObjectWithMember(pre, sym))
+ case Ident(_) =>
+ val packageObject =
+ if (sym.owner.isModuleClass) sym.owner.sourceModule // historical optimization, perhaps no longer needed
+ else pre.typeSymbol.packageObject
+ Ident(packageObject)
case Select(qual, _) => Select(qual, nme.PACKAGEkw)
case SelectFromTypeTree(qual, _) => Select(qual, nme.PACKAGEkw)
}
@@ -928,24 +932,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
def insertApply(): Tree = {
assert(!context.inTypeConstructorAllowed, mode) //@M
val adapted = adaptToName(tree, nme.apply)
- def stabilize0(pre: Type): Tree = stabilize(adapted, pre, MonoQualifierModes, WildcardType)
-
- // TODO reconcile the overlap between Typers#stablize and TreeGen.stabilize
- val qual = adapted match {
- case This(_) =>
- gen.stabilize(adapted)
- case Ident(_) =>
- val owner = adapted.symbol.owner
- val pre =
- if (owner.isPackageClass) owner.thisType
- else if (owner.isClass) context.enclosingSubClassContext(owner).prefix
- else NoPrefix
- stabilize0(pre)
- case Select(qualqual, _) =>
- stabilize0(qualqual.tpe)
- case other =>
- other
- }
+ val qual = gen.stabilize(adapted)
typedPos(tree.pos, mode, pt) {
Select(qual setPos tree.pos.makeTransparent, nme.apply)
}
@@ -2228,7 +2215,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
val allParams = meth.paramss.flatten
for (p <- allParams) {
for (n <- p.deprecatedParamName) {
- if (allParams.exists(p1 => p1.name == n || (p != p1 && p1.deprecatedParamName.exists(_ == n))))
+ if (allParams.exists(p1 => p != p1 && (p1.name == n || p1.deprecatedParamName.exists(_ == n))))
DeprecatedParamNameError(p, n)
}
}
@@ -5228,7 +5215,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
if (refTyped.isErrorTyped) {
setError(tree)
} else {
- tree setType refTyped.tpe.resultType
+ tree setType refTyped.tpe.resultType.deconst
if (refTyped.isErrorTyped || treeInfo.admitsTypeSelection(refTyped)) tree
else UnstableTreeError(tree)
}
diff --git a/src/compiler/scala/tools/reflect/WrappedProperties.scala b/src/compiler/scala/tools/reflect/WrappedProperties.scala
index 523287fc66..348d000d15 100644
--- a/src/compiler/scala/tools/reflect/WrappedProperties.scala
+++ b/src/compiler/scala/tools/reflect/WrappedProperties.scala
@@ -30,9 +30,10 @@ trait WrappedProperties extends PropertiesTrait {
def systemProperties: List[(String, String)] = {
import scala.collection.JavaConverters._
wrap {
+ // SI-7269,7775 Avoid `ConcurrentModificationException` and nulls if another thread modifies properties
val props = System.getProperties
- // SI-7269 Be careful to avoid `ConcurrentModificationException` if another thread modifies the properties map
- props.stringPropertyNames().asScala.toList.map(k => (k, props.get(k).asInstanceOf[String]))
+ val it = props.stringPropertyNames().asScala.iterator map (k => (k, props getProperty k)) filter (_._2 ne null)
+ it.toList
} getOrElse Nil
}
}
diff --git a/src/compiler/scala/tools/util/PathResolver.scala b/src/compiler/scala/tools/util/PathResolver.scala
index 8e5b1e0a5c..f122437b63 100644
--- a/src/compiler/scala/tools/util/PathResolver.scala
+++ b/src/compiler/scala/tools/util/PathResolver.scala
@@ -52,7 +52,7 @@ object PathResolver {
*/
object Environment {
private def searchForBootClasspath =
- systemProperties find (_._1 endsWith ".boot.class.path") map (_._2) getOrElse ""
+ systemProperties collectFirst { case (k, v) if k endsWith ".boot.class.path" => v } getOrElse ""
/** Environment variables which java pays attention to so it
* seems we do as well.
diff --git a/src/eclipse/partest/.classpath b/src/eclipse/partest/.classpath
index 7f28868d95..7e2f119193 100644
--- a/src/eclipse/partest/.classpath
+++ b/src/eclipse/partest/.classpath
@@ -5,7 +5,7 @@
<classpathentry combineaccessrules="false" kind="src" path="/repl"/>
<classpathentry kind="var" path="M2_REPO/com/googlecode/java-diff-utils/diffutils/1.3.0/diffutils-1.3.0.jar"/>
<classpathentry kind="var" path="M2_REPO/org/scala-sbt/test-interface/1.0/test-interface-1.0.jar"/>
- <classpathentry kind="var" path="M2_REPO/org/scala-lang/modules/scala-partest_2.11.0-M7/1.0.0-RC8/scala-partest_2.11.0-M7-1.0.0-RC8.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/scala-lang/modules/scala-partest_2.11/1.0.0/scala-partest_2.11-1.0.0.jar"/>
<classpathentry kind="var" path="SCALA_BASEDIR/lib/ant/ant.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry combineaccessrules="false" kind="src" path="/scala-compiler"/>
diff --git a/src/eclipse/repl/.classpath b/src/eclipse/repl/.classpath
index 8ff9aabfbf..cbaabb9af1 100644
--- a/src/eclipse/repl/.classpath
+++ b/src/eclipse/repl/.classpath
@@ -3,7 +3,6 @@
<classpathentry kind="src" path="repl"/>
<classpathentry combineaccessrules="false" kind="src" path="/asm"/>
<classpathentry kind="var" path="M2_REPO/jline/jline/2.12/jline-2.12.jar"/>
- <!-- <classpathentry kind="var" path="SCALA_BASEDIR/build/deps/repl/jline-2.12.jar"/> -->
<classpathentry combineaccessrules="false" kind="src" path="/scala-compiler"/>
<classpathentry combineaccessrules="false" kind="src" path="/scala-library"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
diff --git a/src/eclipse/scaladoc/.classpath b/src/eclipse/scaladoc/.classpath
index c8f0e89b8a..ee6427176a 100644
--- a/src/eclipse/scaladoc/.classpath
+++ b/src/eclipse/scaladoc/.classpath
@@ -6,8 +6,8 @@
<classpathentry combineaccessrules="false" kind="src" path="/scala-compiler"/>
<classpathentry combineaccessrules="false" kind="src" path="/scala-library"/>
<classpathentry combineaccessrules="false" kind="src" path="/partest-extras"/>
- <classpathentry kind="var" path="M2_REPO/org/scala-lang/modules/scala-xml_2.11.0-M7/1.0.0-RC7/scala-xml_2.11.0-M7-1.0.0-RC7.jar"/>
- <classpathentry kind="var" path="M2_REPO/org/scala-lang/modules/scala-parser-combinators_2.11.0-M7/1.0.0-RC5/scala-parser-combinators_2.11.0-M7-1.0.0-RC5.jar"/>
- <classpathentry kind="var" path="M2_REPO/org/scala-lang/modules/scala-partest_2.11.0-M7/1.0.0-RC8/scala-partest_2.11.0-M7-1.0.0-RC8.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/scala-lang/modules/scala-xml_2.11/1.0.2/scala-xml_2.11-1.0.2.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/scala-lang/modules/scala-parser-combinators_2.11/1.0.1/scala-parser-combinators_2.11-1.0.1.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/scala-lang/modules/scala-partest_2.11/1.0.0/scala-partest_2.11-1.0.0.jar"/>
<classpathentry kind="output" path="build-quick-scaladoc"/>
</classpath>
diff --git a/src/forkjoin/scala/concurrent/forkjoin/ForkJoinPool.java b/src/forkjoin/scala/concurrent/forkjoin/ForkJoinPool.java
index 6578504155..9bd378c61c 100644
--- a/src/forkjoin/scala/concurrent/forkjoin/ForkJoinPool.java
+++ b/src/forkjoin/scala/concurrent/forkjoin/ForkJoinPool.java
@@ -23,6 +23,7 @@ import java.util.concurrent.TimeUnit;
* @since 1.8
* @author Doug Lea
*/
+@Deprecated
/*public*/ abstract class CountedCompleter<T> extends ForkJoinTask<T> {
private static final long serialVersionUID = 5232453752276485070L;
@@ -471,6 +472,7 @@ import java.util.concurrent.TimeUnit;
* @since 1.7
* @author Doug Lea
*/
+@Deprecated
public class ForkJoinPool extends AbstractExecutorService {
/*
@@ -3578,6 +3580,7 @@ public class ForkJoinPool extends AbstractExecutorService {
* }
* }}</pre>
*/
+ @Deprecated
public static interface ManagedBlocker {
/**
* Possibly blocks the current thread, for example waiting for
diff --git a/src/forkjoin/scala/concurrent/forkjoin/ForkJoinTask.java b/src/forkjoin/scala/concurrent/forkjoin/ForkJoinTask.java
index fd1e132b07..b4f5c24ca9 100644
--- a/src/forkjoin/scala/concurrent/forkjoin/ForkJoinTask.java
+++ b/src/forkjoin/scala/concurrent/forkjoin/ForkJoinTask.java
@@ -180,6 +180,7 @@ import java.lang.reflect.Constructor;
* @since 1.7
* @author Doug Lea
*/
+@Deprecated
public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
/*
@@ -391,6 +392,7 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
* any ForkJoinPool will call helpExpungeStaleExceptions when its
* pool becomes isQuiescent.
*/
+ @Deprecated
static final class ExceptionNode extends WeakReference<ForkJoinTask<?>> {
final Throwable ex;
ExceptionNode next;
@@ -1330,6 +1332,7 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
* to be compliant with AbstractExecutorService constraints
* when used in ForkJoinPool.
*/
+ @Deprecated
static final class AdaptedRunnable<T> extends ForkJoinTask<T>
implements RunnableFuture<T> {
final Runnable runnable;
@@ -1349,6 +1352,7 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
/**
* Adaptor for Runnables without results
*/
+ @Deprecated
static final class AdaptedRunnableAction extends ForkJoinTask<Void>
implements RunnableFuture<Void> {
final Runnable runnable;
@@ -1366,6 +1370,7 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
/**
* Adaptor for Callables
*/
+ @Deprecated
static final class AdaptedCallable<T> extends ForkJoinTask<T>
implements RunnableFuture<T> {
final Callable<? extends T> callable;
diff --git a/src/forkjoin/scala/concurrent/forkjoin/ForkJoinWorkerThread.java b/src/forkjoin/scala/concurrent/forkjoin/ForkJoinWorkerThread.java
index e62fc6eb71..e00fb5cc43 100644
--- a/src/forkjoin/scala/concurrent/forkjoin/ForkJoinWorkerThread.java
+++ b/src/forkjoin/scala/concurrent/forkjoin/ForkJoinWorkerThread.java
@@ -20,6 +20,7 @@ package scala.concurrent.forkjoin;
* @since 1.7
* @author Doug Lea
*/
+@Deprecated
public class ForkJoinWorkerThread extends Thread {
/*
* ForkJoinWorkerThreads are managed by ForkJoinPools and perform
diff --git a/src/forkjoin/scala/concurrent/forkjoin/LinkedTransferQueue.java b/src/forkjoin/scala/concurrent/forkjoin/LinkedTransferQueue.java
index 07e81b395d..47d52af895 100644
--- a/src/forkjoin/scala/concurrent/forkjoin/LinkedTransferQueue.java
+++ b/src/forkjoin/scala/concurrent/forkjoin/LinkedTransferQueue.java
@@ -53,6 +53,7 @@ import java.util.concurrent.locks.LockSupport;
* @author Doug Lea
* @param <E> the type of elements held in this collection
*/
+@Deprecated
public class LinkedTransferQueue<E> extends AbstractQueue<E>
implements TransferQueue<E>, java.io.Serializable {
private static final long serialVersionUID = -3223113410248163686L;
@@ -416,6 +417,7 @@ public class LinkedTransferQueue<E> extends AbstractQueue<E>
* unnecessary ordering constraints: Writes that are intrinsically
* ordered wrt other accesses or CASes use simple relaxed forms.
*/
+ @Deprecated
static final class Node {
final boolean isData; // false if this is a request node
volatile Object item; // initially non-null if isData; CASed to match
@@ -789,6 +791,7 @@ public class LinkedTransferQueue<E> extends AbstractQueue<E>
return count;
}
+ @Deprecated
final class Itr implements Iterator<E> {
private Node nextNode; // next node to return item for
private E nextItem; // the corresponding item
diff --git a/src/forkjoin/scala/concurrent/forkjoin/RecursiveAction.java b/src/forkjoin/scala/concurrent/forkjoin/RecursiveAction.java
index 1e7cdd952d..f4a77f0f61 100644
--- a/src/forkjoin/scala/concurrent/forkjoin/RecursiveAction.java
+++ b/src/forkjoin/scala/concurrent/forkjoin/RecursiveAction.java
@@ -133,6 +133,7 @@ package scala.concurrent.forkjoin;
* @since 1.7
* @author Doug Lea
*/
+@Deprecated
public abstract class RecursiveAction extends ForkJoinTask<Void> {
private static final long serialVersionUID = 5232453952276485070L;
diff --git a/src/forkjoin/scala/concurrent/forkjoin/RecursiveTask.java b/src/forkjoin/scala/concurrent/forkjoin/RecursiveTask.java
index d1e1547143..097b7cda1f 100644
--- a/src/forkjoin/scala/concurrent/forkjoin/RecursiveTask.java
+++ b/src/forkjoin/scala/concurrent/forkjoin/RecursiveTask.java
@@ -36,6 +36,7 @@ package scala.concurrent.forkjoin;
* @since 1.7
* @author Doug Lea
*/
+@Deprecated
public abstract class RecursiveTask<V> extends ForkJoinTask<V> {
private static final long serialVersionUID = 5232453952276485270L;
diff --git a/src/forkjoin/scala/concurrent/forkjoin/ThreadLocalRandom.java b/src/forkjoin/scala/concurrent/forkjoin/ThreadLocalRandom.java
index 19237c9092..3ea1af66bc 100644
--- a/src/forkjoin/scala/concurrent/forkjoin/ThreadLocalRandom.java
+++ b/src/forkjoin/scala/concurrent/forkjoin/ThreadLocalRandom.java
@@ -32,6 +32,7 @@ import java.util.Random;
* @since 1.7
* @author Doug Lea
*/
+@Deprecated
public class ThreadLocalRandom extends Random {
// same constants as Random, but must be redeclared because private
private static final long multiplier = 0x5DEECE66DL;
@@ -80,6 +81,7 @@ public class ThreadLocalRandom extends Random {
*
* @return the current thread's {@code ThreadLocalRandom}
*/
+ @Deprecated
public static ThreadLocalRandom current() {
return localRandom.get();
}
diff --git a/src/forkjoin/scala/concurrent/forkjoin/TransferQueue.java b/src/forkjoin/scala/concurrent/forkjoin/TransferQueue.java
index 7d149c7ae5..4fcd8ea601 100644
--- a/src/forkjoin/scala/concurrent/forkjoin/TransferQueue.java
+++ b/src/forkjoin/scala/concurrent/forkjoin/TransferQueue.java
@@ -37,6 +37,7 @@ import java.util.concurrent.*;
* @author Doug Lea
* @param <E> the type of elements held in this collection
*/
+@Deprecated
public interface TransferQueue<E> extends BlockingQueue<E> {
/**
* Transfers the element to a waiting consumer immediately, if possible.
diff --git a/src/forkjoin/scala/concurrent/util/Unsafe.java b/src/forkjoin/scala/concurrent/util/Unsafe.java
index ef893c94d9..d82e4bbdd5 100644
--- a/src/forkjoin/scala/concurrent/util/Unsafe.java
+++ b/src/forkjoin/scala/concurrent/util/Unsafe.java
@@ -7,14 +7,12 @@
\* */
package scala.concurrent.util;
-
-
-
import java.lang.reflect.Field;
-
+@Deprecated
public final class Unsafe {
+ @Deprecated
public final static sun.misc.Unsafe instance;
static {
try {
diff --git a/src/intellij/actors.iml.SAMPLE b/src/intellij/actors.iml.SAMPLE
deleted file mode 100644
index dfdf396c46..0000000000
--- a/src/intellij/actors.iml.SAMPLE
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="JAVA_MODULE" version="4">
- <component name="NewModuleRootManager" inherit-compiler-output="true">
- <exclude-output />
- <content url="file://$MODULE_DIR$/../actors">
- <sourceFolder url="file://$MODULE_DIR$/../actors" isTestSource="false" />
- </content>
- <orderEntry type="inheritedJdk" />
- <orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="module" module-name="library" />
- <orderEntry type="module" module-name="forkjoin" />
- <orderEntry type="library" name="starr" level="project" />
- </component>
-</module> \ No newline at end of file
diff --git a/src/intellij/scala.ipr.SAMPLE b/src/intellij/scala.ipr.SAMPLE
index 47ac2be188..290d53aa5d 100644
--- a/src/intellij/scala.ipr.SAMPLE
+++ b/src/intellij/scala.ipr.SAMPLE
@@ -35,7 +35,6 @@
</component>
<component name="ProjectModuleManager">
<modules>
- <module fileurl="file://$PROJECT_DIR$/actors.iml" filepath="$PROJECT_DIR$/actors.iml" />
<module fileurl="file://$PROJECT_DIR$/compiler.iml" filepath="$PROJECT_DIR$/compiler.iml" />
<module fileurl="file://$PROJECT_DIR$/forkjoin.iml" filepath="$PROJECT_DIR$/forkjoin.iml" />
<module fileurl="file://$PROJECT_DIR$/interactive.iml" filepath="$PROJECT_DIR$/interactive.iml" />
diff --git a/src/intellij/test-junit.iml.SAMPLE b/src/intellij/test-junit.iml.SAMPLE
index 86dc39c175..8252ef6d98 100644
--- a/src/intellij/test-junit.iml.SAMPLE
+++ b/src/intellij/test-junit.iml.SAMPLE
@@ -7,7 +7,6 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="module" module-name="actors" />
<orderEntry type="module" module-name="compiler" />
<orderEntry type="module" module-name="forkjoin" />
<orderEntry type="module" module-name="library" />
diff --git a/src/intellij/test.iml.SAMPLE b/src/intellij/test.iml.SAMPLE
index 5047967721..e7eb7576c3 100644
--- a/src/intellij/test.iml.SAMPLE
+++ b/src/intellij/test.iml.SAMPLE
@@ -7,7 +7,6 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="module" module-name="actors" />
<orderEntry type="module" module-name="compiler" />
<orderEntry type="module" module-name="forkjoin" />
<orderEntry type="module" module-name="interactive" />
diff --git a/src/interactive/scala/tools/nsc/interactive/Global.scala b/src/interactive/scala/tools/nsc/interactive/Global.scala
index 727bfdd510..e79c1a01ab 100644
--- a/src/interactive/scala/tools/nsc/interactive/Global.scala
+++ b/src/interactive/scala/tools/nsc/interactive/Global.scala
@@ -19,6 +19,8 @@ import scala.annotation.{ elidable, tailrec }
import scala.language.implicitConversions
import scala.tools.nsc.typechecker.Typers
import scala.util.control.Breaks._
+import java.util.concurrent.ConcurrentHashMap
+import scala.collection.JavaConverters.mapAsScalaMapConverter
/**
* This trait allows the IDE to have an instance of the PC that
@@ -157,33 +159,20 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
override def forInteractive = true
override protected def synchronizeNames = true
- override def newAsSeenFromMap(pre: Type, clazz: Symbol): AsSeenFromMap =
- new InteractiveAsSeenFromMap(pre, clazz)
-
- class InteractiveAsSeenFromMap(pre: Type, clazz: Symbol) extends AsSeenFromMap(pre, clazz) {
- /** The method formerly known as 'instParamsRelaxed' goes here if it's still necessary,
- * which it is currently supposed it is not.
- *
- * If it is, change AsSeenFromMap method correspondingTypeArgument to call an overridable
- * method rather than aborting in the failure case.
- */
- }
-
/** A map of all loaded files to the rich compilation units that correspond to them.
*/
- val unitOfFile = new LinkedHashMap[AbstractFile, RichCompilationUnit] with
- SynchronizedMap[AbstractFile, RichCompilationUnit] {
+ val unitOfFile = mapAsScalaMapConverter(new ConcurrentHashMap[AbstractFile, RichCompilationUnit] {
override def put(key: AbstractFile, value: RichCompilationUnit) = {
val r = super.put(key, value)
- if (r.isEmpty) debugLog("added unit for "+key)
+ if (r == null) debugLog("added unit for "+key)
r
}
- override def remove(key: AbstractFile) = {
+ override def remove(key: Any) = {
val r = super.remove(key)
- if (r.nonEmpty) debugLog("removed unit for "+key)
+ if (r != null) debugLog("removed unit for "+key)
r
}
- }
+ }).asScala
/** A set containing all those files that need to be removed
* Units are removed by getUnit, typically once a unit is finished compiled.
@@ -1101,7 +1090,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
val implicitlyAdded = viaView != NoSymbol
members.add(sym, pre, implicitlyAdded) { (s, st) =>
new TypeMember(s, st,
- context.isAccessible(if (s.hasGetter) s.getter(s.owner) else s, pre, superAccess && !implicitlyAdded),
+ context.isAccessible(if (s.hasGetter) s.getterIn(s.owner) else s, pre, superAccess && !implicitlyAdded),
inherited,
viaView)
}
diff --git a/src/library/rootdoc.txt b/src/library/rootdoc.txt
index e84942b8c4..95f9836cc9 100644
--- a/src/library/rootdoc.txt
+++ b/src/library/rootdoc.txt
@@ -44,12 +44,8 @@ Additional parts of the standard library are shipped as separate libraries. Thes
- [[scala.reflect `scala.reflect`]] - Scala's reflection API (scala-reflect.jar)
- [[scala.xml `scala.xml`]] - XML parsing, manipulation, and serialization (scala-xml.jar)
- [[scala.swing `scala.swing`]] - A convenient wrapper around Java's GUI framework called Swing (scala-swing.jar)
- - [[scala.util.continuations `scala.util.continuations`]] - Delimited continuations using continuation-passing-style
- (scala-continuations-library.jar, scala-continuations-plugin.jar)
- [[scala.util.parsing `scala.util.parsing`]] - [[scala.util.parsing.combinator Parser combinators]], including an
example implementation of a [[scala.util.parsing.json JSON parser]] (scala-parser-combinators.jar)
- - [[scala.actors `scala.actors`]] - Actor-based concurrency (deprecated and replaced by Akka actors,
- scala-actors.jar)
== Automatic imports ==
diff --git a/src/library/scala/PartialFunction.scala b/src/library/scala/PartialFunction.scala
index fba759eb32..98dd35d306 100644
--- a/src/library/scala/PartialFunction.scala
+++ b/src/library/scala/PartialFunction.scala
@@ -161,10 +161,10 @@ trait PartialFunction[-A, +B] extends (A => B) { self =>
object PartialFunction {
/** Composite function produced by `PartialFunction#orElse` method
*/
- private class OrElse[-A, +B] (f1: PartialFunction[A, B], f2: PartialFunction[A, B]) extends PartialFunction[A, B] {
+ private class OrElse[-A, +B] (f1: PartialFunction[A, B], f2: PartialFunction[A, B]) extends scala.runtime.AbstractPartialFunction[A, B] {
def isDefinedAt(x: A) = f1.isDefinedAt(x) || f2.isDefinedAt(x)
- def apply(x: A): B = f1.applyOrElse(x, f2)
+ override def apply(x: A): B = f1.applyOrElse(x, f2)
override def applyOrElse[A1 <: A, B1 >: B](x: A1, default: A1 => B1): B1 = {
val z = f1.applyOrElse(x, checkFallback[B])
diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala
index 0f300412b7..012e7afd74 100644
--- a/src/library/scala/Predef.scala
+++ b/src/library/scala/Predef.scala
@@ -126,7 +126,7 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef {
def optManifest[T](implicit m: OptManifest[T]) = m
// Minor variations on identity functions
- def identity[A](x: A): A = x // @see `conforms` for the implicit version
+ @inline def identity[A](x: A): A = x // @see `conforms` for the implicit version
@inline def implicitly[T](implicit e: T) = e // for summoning implicit values from the nether world -- TODO: when dependent method types are on by default, give this result type `e.type`, so that inliner has better chance of knowing which method to inline in calls like `implicitly[MatchingStrategy[Option]].zero`
@inline def locally[T](x: T): T = x // to communicate intent and avoid unmoored statements
@@ -329,16 +329,28 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef {
case null => null
}).asInstanceOf[ArrayOps[T]]
- implicit def booleanArrayOps(xs: Array[Boolean]): ArrayOps[Boolean] = new ArrayOps.ofBoolean(xs)
- implicit def byteArrayOps(xs: Array[Byte]): ArrayOps[Byte] = new ArrayOps.ofByte(xs)
- implicit def charArrayOps(xs: Array[Char]): ArrayOps[Char] = new ArrayOps.ofChar(xs)
- implicit def doubleArrayOps(xs: Array[Double]): ArrayOps[Double] = new ArrayOps.ofDouble(xs)
- implicit def floatArrayOps(xs: Array[Float]): ArrayOps[Float] = new ArrayOps.ofFloat(xs)
- implicit def intArrayOps(xs: Array[Int]): ArrayOps[Int] = new ArrayOps.ofInt(xs)
- implicit def longArrayOps(xs: Array[Long]): ArrayOps[Long] = new ArrayOps.ofLong(xs)
- implicit def refArrayOps[T <: AnyRef](xs: Array[T]): ArrayOps[T] = new ArrayOps.ofRef[T](xs)
- implicit def shortArrayOps(xs: Array[Short]): ArrayOps[Short] = new ArrayOps.ofShort(xs)
- implicit def unitArrayOps(xs: Array[Unit]): ArrayOps[Unit] = new ArrayOps.ofUnit(xs)
+ // TODO: when we remove, these should we drop the underscores from the new generation below? (For source compatibility in case someone was shadowing these.)
+ @deprecated("For binary compatibility only. Release new partest and remove in M3.", "2.12.0-M2") def booleanArrayOps(xs: Array[Boolean]): ArrayOps[Boolean] = new ArrayOps.ofBoolean(xs)
+ @deprecated("For binary compatibility only. Release new partest and remove in M3.", "2.12.0-M2") def byteArrayOps(xs: Array[Byte]): ArrayOps[Byte] = new ArrayOps.ofByte(xs)
+ @deprecated("For binary compatibility only. Release new partest and remove in M3.", "2.12.0-M2") def charArrayOps(xs: Array[Char]): ArrayOps[Char] = new ArrayOps.ofChar(xs)
+ @deprecated("For binary compatibility only. Release new partest and remove in M3.", "2.12.0-M2") def doubleArrayOps(xs: Array[Double]): ArrayOps[Double] = new ArrayOps.ofDouble(xs)
+ @deprecated("For binary compatibility only. Release new partest and remove in M3.", "2.12.0-M2") def floatArrayOps(xs: Array[Float]): ArrayOps[Float] = new ArrayOps.ofFloat(xs)
+ @deprecated("For binary compatibility only. Release new partest and remove in M3.", "2.12.0-M2") def intArrayOps(xs: Array[Int]): ArrayOps[Int] = new ArrayOps.ofInt(xs)
+ @deprecated("For binary compatibility only. Release new partest and remove in M3.", "2.12.0-M2") def longArrayOps(xs: Array[Long]): ArrayOps[Long] = new ArrayOps.ofLong(xs)
+ @deprecated("For binary compatibility only. Release new partest and remove in M3.", "2.12.0-M2") def refArrayOps[T <: AnyRef](xs: Array[T]): ArrayOps[T] = new ArrayOps.ofRef[T](xs)
+ @deprecated("For binary compatibility only. Release new partest and remove in M3.", "2.12.0-M2") def shortArrayOps(xs: Array[Short]): ArrayOps[Short] = new ArrayOps.ofShort(xs)
+ @deprecated("For binary compatibility only. Release new partest and remove in M3.", "2.12.0-M2") def unitArrayOps(xs: Array[Unit]): ArrayOps[Unit] = new ArrayOps.ofUnit(xs)
+
+ implicit def _booleanArrayOps(xs: Array[Boolean]): ArrayOps.ofBoolean = new ArrayOps.ofBoolean(xs)
+ implicit def _byteArrayOps(xs: Array[Byte]): ArrayOps.ofByte = new ArrayOps.ofByte(xs)
+ implicit def _charArrayOps(xs: Array[Char]): ArrayOps.ofChar = new ArrayOps.ofChar(xs)
+ implicit def _doubleArrayOps(xs: Array[Double]): ArrayOps.ofDouble = new ArrayOps.ofDouble(xs)
+ implicit def _floatArrayOps(xs: Array[Float]): ArrayOps.ofFloat = new ArrayOps.ofFloat(xs)
+ implicit def _intArrayOps(xs: Array[Int]): ArrayOps.ofInt = new ArrayOps.ofInt(xs)
+ implicit def _longArrayOps(xs: Array[Long]): ArrayOps.ofLong = new ArrayOps.ofLong(xs)
+ implicit def _refArrayOps[T <: AnyRef](xs: Array[T]): ArrayOps.ofRef[T] = new ArrayOps.ofRef[T](xs)
+ implicit def _shortArrayOps(xs: Array[Short]): ArrayOps.ofShort = new ArrayOps.ofShort(xs)
+ implicit def _unitArrayOps(xs: Array[Unit]): ArrayOps.ofUnit = new ArrayOps.ofUnit(xs)
// "Autoboxing" and "Autounboxing" ---------------------------------------------------
diff --git a/src/library/scala/beans/BeanInfo.scala b/src/library/scala/beans/BeanInfo.scala
index 799e93e71a..d7f0a1618b 100644
--- a/src/library/scala/beans/BeanInfo.scala
+++ b/src/library/scala/beans/BeanInfo.scala
@@ -17,4 +17,5 @@ package scala.beans
*
* @author Ross Judson (rjudson@managedobjects.com)
*/
+@deprecated(message = "the generation of BeanInfo classes is no longer supported", since = "2.12.0")
class BeanInfo extends scala.annotation.Annotation
diff --git a/src/library/scala/collection/IterableViewLike.scala b/src/library/scala/collection/IterableViewLike.scala
index b84d90c51b..c254ed7480 100644
--- a/src/library/scala/collection/IterableViewLike.scala
+++ b/src/library/scala/collection/IterableViewLike.scala
@@ -69,6 +69,10 @@ trait IterableViewLike[+A,
trait Appended[B >: A] extends super.Appended[B] with Transformed[B] {
def iterator = self.iterator ++ rest
}
+
+ trait Prepended[B >: A] extends super.Prepended[B] with Transformed[B] {
+ def iterator = fst.toIterator ++ self
+ }
trait Filtered extends super.Filtered with Transformed[A] {
def iterator = self.iterator filter pred
@@ -110,6 +114,7 @@ trait IterableViewLike[+A,
} with AbstractTransformed[(A1, B)] with ZippedAll[A1, B]
protected override def newForced[B](xs: => GenSeq[B]): Transformed[B] = new { val forced = xs } with AbstractTransformed[B] with Forced[B]
protected override def newAppended[B >: A](that: GenTraversable[B]): Transformed[B] = new { val rest = that } with AbstractTransformed[B] with Appended[B]
+ protected override def newPrepended[B >: A](that: GenTraversable[B]): Transformed[B] = new { val fst = that } with AbstractTransformed[B] with Prepended[B]
protected override def newMapped[B](f: A => B): Transformed[B] = new { val mapping = f } with AbstractTransformed[B] with Mapped[B]
protected override def newFlatMapped[B](f: A => GenTraversableOnce[B]): Transformed[B] = new { val mapping = f } with AbstractTransformed[B] with FlatMapped[B]
protected override def newFiltered(p: A => Boolean): Transformed[A] = new { val pred = p } with AbstractTransformed[A] with Filtered
diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala
index c9037eb3e3..e2c271145d 100644
--- a/src/library/scala/collection/Iterator.scala
+++ b/src/library/scala/collection/Iterator.scala
@@ -182,7 +182,7 @@ object Iterator {
}
}
def hasNext = (current ne null) && (current.hasNext || advance())
- def next() = if (hasNext) current.next else Iterator.empty.next
+ def next() = if (hasNext) current.next() else Iterator.empty.next()
override def ++[B >: A](that: => GenTraversableOnce[B]): Iterator[B] =
new ConcatIterator(current, queue :+ (() => that.toIterator))
@@ -191,11 +191,55 @@ object Iterator {
private[scala] final class JoinIterator[+A](lhs: Iterator[A], that: => GenTraversableOnce[A]) extends Iterator[A] {
private[this] lazy val rhs: Iterator[A] = that.toIterator
def hasNext = lhs.hasNext || rhs.hasNext
- def next = if (lhs.hasNext) lhs.next else rhs.next
+ def next() = if (lhs.hasNext) lhs.next() else rhs.next()
override def ++[B >: A](that: => GenTraversableOnce[B]) =
new ConcatIterator(this, Vector(() => that.toIterator))
}
+
+ /** Creates a delegating iterator capped by a limit count. Negative limit means unbounded.
+ * Lazily skip to start on first evaluation. Avoids daisy-chained iterators due to slicing.
+ */
+ private[scala] final class SliceIterator[A](val underlying: Iterator[A], start: Int, limit: Int) extends AbstractIterator[A] {
+ private var remaining = limit
+ private var dropping = start
+ @inline private def unbounded = remaining < 0
+ private def skip(): Unit =
+ while (dropping > 0) {
+ if (underlying.hasNext) {
+ underlying.next()
+ dropping -= 1
+ } else
+ dropping = 0
+ }
+ def hasNext = { skip(); remaining != 0 && underlying.hasNext }
+ def next() = {
+ skip()
+ if (remaining > 0) {
+ remaining -= 1
+ underlying.next()
+ }
+ else if (unbounded) underlying.next()
+ else empty.next()
+ }
+ override protected def sliceIterator(from: Int, until: Int): Iterator[A] = {
+ val lo = from max 0
+ def adjustedBound =
+ if (unbounded) -1
+ else 0 max (remaining - lo)
+ val rest =
+ if (until < 0) adjustedBound // respect current bound, if any
+ else if (until <= lo) 0 // empty
+ else if (unbounded) until - lo // now finite
+ else adjustedBound min (until - lo) // keep lesser bound
+ if (rest == 0) empty
+ else {
+ dropping += lo
+ remaining = rest
+ this
+ }
+ }
+ }
}
import Iterator.empty
@@ -307,11 +351,11 @@ trait Iterator[+A] extends TraversableOnce[A] {
/** Selects first ''n'' values of this iterator.
*
* @param n the number of values to take
- * @return an iterator producing only of the first `n` values of this iterator, or else the
+ * @return an iterator producing only the first `n` values of this iterator, or else the
* whole iterator, if it produces fewer than `n` values.
* @note Reuse: $consumesAndProducesIterator
*/
- def take(n: Int): Iterator[A] = slice(0, n)
+ def take(n: Int): Iterator[A] = sliceIterator(0, n max 0)
/** Advances this iterator past the first ''n'' elements, or the length of the iterator, whichever is smaller.
*
@@ -332,29 +376,24 @@ trait Iterator[+A] extends TraversableOnce[A] {
/** Creates an iterator returning an interval of the values produced by this iterator.
*
* @param from the index of the first element in this iterator which forms part of the slice.
- * @param until the index of the first element following the slice.
+ * If negative, the slice starts at zero.
+ * @param until the index of the first element following the slice. If negative, the slice is empty.
* @return an iterator which advances this iterator past the first `from` elements using `drop`,
* and then takes `until - from` elements, using `take`.
* @note Reuse: $consumesAndProducesIterator
*/
- def slice(from: Int, until: Int): Iterator[A] = {
+ def slice(from: Int, until: Int): Iterator[A] = sliceIterator(from, until max 0)
+
+ /** Creates an optionally bounded slice, unbounded if `until` is negative. */
+ protected def sliceIterator(from: Int, until: Int): Iterator[A] = {
val lo = from max 0
- var toDrop = lo
- while (toDrop > 0 && self.hasNext) {
- self.next()
- toDrop -= 1
- }
+ val rest =
+ if (until < 0) -1 // unbounded
+ else if (until <= lo) 0 // empty
+ else until - lo // finite
- new AbstractIterator[A] {
- private var remaining = until - lo
- def hasNext = remaining > 0 && self.hasNext
- def next(): A =
- if (remaining > 0) {
- remaining -= 1
- self.next()
- }
- else empty.next()
- }
+ if (rest == 0) empty
+ else new Iterator.SliceIterator(this, lo, rest)
}
/** Creates a new iterator that maps all produced values of this iterator
@@ -805,8 +844,25 @@ trait Iterator[+A] extends TraversableOnce[A] {
* or -1 if such an element does not exist until the end of the iterator is reached.
* @note Reuse: $consumesIterator
*/
- def indexWhere(p: A => Boolean): Int = {
+ def indexWhere(p: A => Boolean): Int = indexWhere(p, 0)
+
+ /** Returns the index of the first produced value satisfying a predicate, or -1, after or at
+ * some start index.
+ * $mayNotTerminateInf
+ *
+ * @param p the predicate to test values
+ * @param from the start index
+ * @return the index `>= from` of the first produced value satisfying `p`,
+ * or -1 if such an element does not exist until the end of the iterator is reached.
+ * @note Reuse: $consumesIterator
+ */
+ def indexWhere(p: A => Boolean, from: Int): Int = {
var i = 0
+ while (i < from && hasNext) {
+ next()
+ i += 1
+ }
+
var found = false
while (!found && hasNext) {
if (p(next())) {
@@ -827,8 +883,26 @@ trait Iterator[+A] extends TraversableOnce[A] {
* or -1 if such an element does not exist until the end of the iterator is reached.
* @note Reuse: $consumesIterator
*/
- def indexOf[B >: A](elem: B): Int = {
+ def indexOf[B >: A](elem: B): Int = indexOf(elem, 0)
+
+ /** Returns the index of the first occurrence of the specified object in this iterable object
+ * after or at some start index.
+ * $mayNotTerminateInf
+ *
+ * @param elem element to search for.
+ * @param from the start index
+ * @return the index `>= from` of the first occurrence of `elem` in the values produced by this
+ * iterator, or -1 if such an element does not exist until the end of the iterator is
+ * reached.
+ * @note Reuse: $consumesIterator
+ */
+ def indexOf[B >: A](elem: B, from: Int): Int = {
var i = 0
+ while (i < from && hasNext) {
+ next()
+ i += 1
+ }
+
var found = false
while (!found && hasNext) {
if (next() == elem) {
@@ -1147,9 +1221,8 @@ trait Iterator[+A] extends TraversableOnce[A] {
* $willNotTerminateInf
*/
def copyToArray[B >: A](xs: Array[B], start: Int, len: Int): Unit = {
- require(start >= 0 && (start < xs.length || xs.length == 0), s"start $start out of range ${xs.length}")
var i = start
- val end = start + math.min(len, xs.length - start)
+ val end = start + math.min(len, xs.length - start)
while (i < end && hasNext) {
xs(i) = next()
i += 1
diff --git a/src/library/scala/collection/MapLike.scala b/src/library/scala/collection/MapLike.scala
index d133400570..b474abc12a 100644
--- a/src/library/scala/collection/MapLike.scala
+++ b/src/library/scala/collection/MapLike.scala
@@ -230,11 +230,15 @@ self =>
protected class FilteredKeys(p: A => Boolean) extends AbstractMap[A, B] with DefaultMap[A, B] {
override def foreach[C](f: ((A, B)) => C): Unit = for (kv <- self) if (p(kv._1)) f(kv)
def iterator = self.iterator.filter(kv => p(kv._1))
- override def contains(key: A) = self.contains(key) && p(key)
+ override def contains(key: A) = p(key) && self.contains(key)
def get(key: A) = if (!p(key)) None else self.get(key)
}
/** Filters this map by retaining only keys satisfying a predicate.
+ *
+ * '''Note''': the predicate must accept any key of type `A`, not just those already
+ * present in the map, as the predicate is tested before the underlying map is queried.
+ *
* @param p the predicate used to test keys
* @return an immutable map consisting only of those key value pairs of this map where the key satisfies
* the predicate `p`. The resulting map wraps the original map without copying any elements.
@@ -319,11 +323,20 @@ self =>
res
}
- /* Overridden for efficiency. */
- override def toSeq: Seq[(A, B)] = toBuffer[(A, B)]
+ override def toSeq: Seq[(A, B)] = {
+ if (isEmpty) Vector.empty[(A, B)]
+ else {
+ // Default appropriate for immutable collections; mutable collections override this
+ val vb = Vector.newBuilder[(A, B)]
+ foreach(vb += _)
+ vb.result
+ }
+ }
+
override def toBuffer[C >: (A, B)]: mutable.Buffer[C] = {
val result = new mutable.ArrayBuffer[C](size)
- copyToBuffer(result)
+ // Faster to let the map iterate itself than to defer through copyToBuffer
+ foreach(result += _)
result
}
diff --git a/src/library/scala/collection/SeqViewLike.scala b/src/library/scala/collection/SeqViewLike.scala
index 3473c8aff1..1fbcb6531e 100644
--- a/src/library/scala/collection/SeqViewLike.scala
+++ b/src/library/scala/collection/SeqViewLike.scala
@@ -96,6 +96,14 @@ trait SeqViewLike[+A,
if (idx < self.length) self(idx) else restSeq(idx - self.length)
}
+ trait Prepended[B >: A] extends super.Prepended[B] with Transformed[B] {
+ protected[this] lazy val fstSeq = fst.toSeq
+ def length: Int = fstSeq.length + self.length
+ def apply(idx: Int): B =
+ if (idx < fstSeq.length) fstSeq(idx)
+ else self.apply(idx - fstSeq.length)
+ }
+
trait Filtered extends super.Filtered with Transformed[A] {
protected[this] lazy val index = {
var len = 0
@@ -179,21 +187,12 @@ trait SeqViewLike[+A,
final override protected[this] def viewIdentifier = "P"
}
- trait Prepended[B >: A] extends Transformed[B] {
- protected[this] val fst: B
- override def iterator: Iterator[B] = Iterator.single(fst) ++ self.iterator
- def length: Int = 1 + self.length
- def apply(idx: Int): B =
- if (idx == 0) fst
- else self.apply(idx - 1)
- final override protected[this] def viewIdentifier = "A"
- }
-
/** Boilerplate method, to override in each subclass
* This method could be eliminated if Scala had virtual classes
*/
protected override def newForced[B](xs: => GenSeq[B]): Transformed[B] = new { val forced = xs } with AbstractTransformed[B] with Forced[B]
protected override def newAppended[B >: A](that: GenTraversable[B]): Transformed[B] = new { val rest = that } with AbstractTransformed[B] with Appended[B]
+ protected override def newPrepended[B >: A](that: GenTraversable[B]): Transformed[B] = new { protected[this] val fst = that } with AbstractTransformed[B] with Prepended[B]
protected override def newMapped[B](f: A => B): Transformed[B] = new { val mapping = f } with AbstractTransformed[B] with Mapped[B]
protected override def newFlatMapped[B](f: A => GenTraversableOnce[B]): Transformed[B] = new { val mapping = f } with AbstractTransformed[B] with FlatMapped[B]
protected override def newFiltered(p: A => Boolean): Transformed[A] = new { val pred = p } with AbstractTransformed[A] with Filtered
@@ -212,7 +211,6 @@ trait SeqViewLike[+A,
val patch = _patch
val replaced = _replaced
} with AbstractTransformed[B] with Patched[B]
- protected def newPrepended[B >: A](elem: B): Transformed[B] = new { protected[this] val fst = elem } with AbstractTransformed[B] with Prepended[B]
// see comment in IterableViewLike.
protected override def newTaken(n: Int): Transformed[A] = newSliced(SliceInterval(0, n))
@@ -242,7 +240,7 @@ trait SeqViewLike[+A,
}
override def +:[B >: A, That](elem: B)(implicit bf: CanBuildFrom[This, B, That]): That =
- newPrepended(elem).asInstanceOf[That]
+ newPrepended(elem :: Nil).asInstanceOf[That]
override def :+[B >: A, That](elem: B)(implicit bf: CanBuildFrom[This, B, That]): That =
++(Iterator.single(elem))(bf)
diff --git a/src/library/scala/collection/SetLike.scala b/src/library/scala/collection/SetLike.scala
index f8ac1d754d..d03c808c2c 100644
--- a/src/library/scala/collection/SetLike.scala
+++ b/src/library/scala/collection/SetLike.scala
@@ -77,11 +77,20 @@ self =>
protected[this] override def parCombiner = ParSet.newCombiner[A]
- /* Overridden for efficiency. */
- override def toSeq: Seq[A] = toBuffer[A]
+ // Default collection type appropriate for immutable collections; mutable collections override this
+ override def toSeq: Seq[A] = {
+ if (isEmpty) Vector.empty[A]
+ else {
+ val vb = Vector.newBuilder[A]
+ foreach(vb += _)
+ vb.result
+ }
+ }
+
override def toBuffer[A1 >: A]: mutable.Buffer[A1] = {
val result = new mutable.ArrayBuffer[A1](size)
- copyToBuffer(result)
+ // Faster to let the map iterate itself than to defer through copyToBuffer
+ foreach(result += _)
result
}
diff --git a/src/library/scala/collection/TraversableLike.scala b/src/library/scala/collection/TraversableLike.scala
index 96374ef653..f187a7a655 100644
--- a/src/library/scala/collection/TraversableLike.scala
+++ b/src/library/scala/collection/TraversableLike.scala
@@ -253,7 +253,7 @@ trait TraversableLike[+A, +Repr] extends Any
b.result
}
- private def filterImpl(p: A => Boolean, isFlipped: Boolean): Repr = {
+ private[scala] def filterImpl(p: A => Boolean, isFlipped: Boolean): Repr = {
val b = newBuilder
for (x <- this)
if (p(x) != isFlipped) b += x
diff --git a/src/library/scala/collection/TraversableViewLike.scala b/src/library/scala/collection/TraversableViewLike.scala
index 5926c69ebf..0901d749c3 100644
--- a/src/library/scala/collection/TraversableViewLike.scala
+++ b/src/library/scala/collection/TraversableViewLike.scala
@@ -189,6 +189,15 @@ trait TraversableViewLike[+A,
}
final override protected[this] def viewIdentifier = "A"
}
+
+ trait Prepended[B >: A] extends Transformed[B] {
+ protected[this] val fst: GenTraversable[B]
+ def foreach[U](f: B => U) {
+ fst foreach f
+ self foreach f
+ }
+ final override protected[this] def viewIdentifier = "A"
+ }
trait Filtered extends Transformed[A] {
protected[this] val pred: A => Boolean
@@ -222,11 +231,15 @@ trait TraversableViewLike[+A,
final override protected[this] def viewIdentifier = "D"
}
- override def ++[B >: A, That](xs: GenTraversableOnce[B])(implicit bf: CanBuildFrom[This, B, That]): That = {
+ override def ++[B >: A, That](xs: GenTraversableOnce[B])(implicit bf: CanBuildFrom[This, B, That]): That =
newAppended(xs.seq.toTraversable).asInstanceOf[That]
-// was: if (bf.isInstanceOf[ByPassCanBuildFrom]) newAppended(that).asInstanceOf[That]
-// else super.++[B, That](that)(bf)
- }
+
+ override def ++:[B >: A, That](xs: TraversableOnce[B])(implicit bf: CanBuildFrom[This, B, That]): That =
+ newPrepended(xs.seq.toTraversable).asInstanceOf[That]
+
+ // Need second one because of optimization in TraversableLike
+ override def ++:[B >: A, That](xs: Traversable[B])(implicit bf: CanBuildFrom[This, B, That]): That =
+ newPrepended(xs).asInstanceOf[That]
override def map[B, That](f: A => B)(implicit bf: CanBuildFrom[This, B, That]): That = {
newMapped(f).asInstanceOf[That]
@@ -253,6 +266,7 @@ trait TraversableViewLike[+A,
*/
protected def newForced[B](xs: => GenSeq[B]): Transformed[B] = new { val forced = xs } with AbstractTransformed[B] with Forced[B]
protected def newAppended[B >: A](that: GenTraversable[B]): Transformed[B] = new { val rest = that } with AbstractTransformed[B] with Appended[B]
+ protected def newPrepended[B >: A](that: GenTraversable[B]): Transformed[B] = new { val fst = that } with AbstractTransformed[B] with Prepended[B]
protected def newMapped[B](f: A => B): Transformed[B] = new { val mapping = f } with AbstractTransformed[B] with Mapped[B]
protected def newFlatMapped[B](f: A => GenTraversableOnce[B]): Transformed[B] = new { val mapping = f } with AbstractTransformed[B] with FlatMapped[B]
protected def newFiltered(p: A => Boolean): Transformed[A] = new { val pred = p } with AbstractTransformed[A] with Filtered
diff --git a/src/library/scala/collection/concurrent/Map.scala b/src/library/scala/collection/concurrent/Map.scala
index cfb567abe9..f27dfd57fc 100644
--- a/src/library/scala/collection/concurrent/Map.scala
+++ b/src/library/scala/collection/concurrent/Map.scala
@@ -86,4 +86,15 @@ trait Map[A, B] extends scala.collection.mutable.Map[A, B] {
* @return `Some(v)` if the given key was previously mapped to some value `v`, or `None` otherwise
*/
def replace(k: A, v: B): Option[B]
+
+ override def getOrElseUpdate(key: A, op: =>B): B = get(key) match {
+ case Some(v) => v
+ case None =>
+ val v = op
+ putIfAbsent(key, v) match {
+ case Some(nv) => nv
+ case None => v
+ }
+ }
+
}
diff --git a/src/library/scala/collection/convert/WrapAsJava.scala b/src/library/scala/collection/convert/WrapAsJava.scala
index 9916fe9843..e97a2ff1fc 100644
--- a/src/library/scala/collection/convert/WrapAsJava.scala
+++ b/src/library/scala/collection/convert/WrapAsJava.scala
@@ -30,8 +30,9 @@ trait WrapAsJava {
* @return A Java Iterator view of the argument.
*/
implicit def asJavaIterator[A](it: Iterator[A]): ju.Iterator[A] = it match {
- case JIteratorWrapper(wrapped) => wrapped.asInstanceOf[ju.Iterator[A]]
- case _ => IteratorWrapper(it)
+ case null => null
+ case JIteratorWrapper(wrapped) => wrapped.asInstanceOf[ju.Iterator[A]]
+ case _ => IteratorWrapper(it)
}
/**
@@ -48,8 +49,9 @@ trait WrapAsJava {
* @return A Java Enumeration view of the argument.
*/
implicit def asJavaEnumeration[A](it: Iterator[A]): ju.Enumeration[A] = it match {
+ case null => null
case JEnumerationWrapper(wrapped) => wrapped.asInstanceOf[ju.Enumeration[A]]
- case _ => IteratorWrapper(it)
+ case _ => IteratorWrapper(it)
}
/**
@@ -66,8 +68,9 @@ trait WrapAsJava {
* @return A Java Iterable view of the argument.
*/
implicit def asJavaIterable[A](i: Iterable[A]): jl.Iterable[A] = i match {
- case JIterableWrapper(wrapped) => wrapped.asInstanceOf[jl.Iterable[A]]
- case _ => IterableWrapper(i)
+ case null => null
+ case JIterableWrapper(wrapped) => wrapped.asInstanceOf[jl.Iterable[A]]
+ case _ => IterableWrapper(i)
}
/**
@@ -82,8 +85,9 @@ trait WrapAsJava {
* @return A Java Collection view of the argument.
*/
implicit def asJavaCollection[A](it: Iterable[A]): ju.Collection[A] = it match {
- case JCollectionWrapper(wrapped) => wrapped.asInstanceOf[ju.Collection[A]]
- case _ => new IterableWrapper(it)
+ case null => null
+ case JCollectionWrapper(wrapped) => wrapped.asInstanceOf[ju.Collection[A]]
+ case _ => new IterableWrapper(it)
}
/**
@@ -100,8 +104,9 @@ trait WrapAsJava {
* @return A Java List view of the argument.
*/
implicit def bufferAsJavaList[A](b: mutable.Buffer[A]): ju.List[A] = b match {
- case JListWrapper(wrapped) => wrapped
- case _ => new MutableBufferWrapper(b)
+ case null => null
+ case JListWrapper(wrapped) => wrapped
+ case _ => new MutableBufferWrapper(b)
}
/**
@@ -118,8 +123,9 @@ trait WrapAsJava {
* @return A Java List view of the argument.
*/
implicit def mutableSeqAsJavaList[A](seq: mutable.Seq[A]): ju.List[A] = seq match {
- case JListWrapper(wrapped) => wrapped
- case _ => new MutableSeqWrapper(seq)
+ case null => null
+ case JListWrapper(wrapped) => wrapped
+ case _ => new MutableSeqWrapper(seq)
}
/**
@@ -136,8 +142,9 @@ trait WrapAsJava {
* @return A Java List view of the argument.
*/
implicit def seqAsJavaList[A](seq: Seq[A]): ju.List[A] = seq match {
- case JListWrapper(wrapped) => wrapped.asInstanceOf[ju.List[A]]
- case _ => new SeqWrapper(seq)
+ case null => null
+ case JListWrapper(wrapped) => wrapped.asInstanceOf[ju.List[A]]
+ case _ => new SeqWrapper(seq)
}
/**
@@ -154,8 +161,9 @@ trait WrapAsJava {
* @return A Java Set view of the argument.
*/
implicit def mutableSetAsJavaSet[A](s: mutable.Set[A]): ju.Set[A] = s match {
+ case null => null
case JSetWrapper(wrapped) => wrapped
- case _ => new MutableSetWrapper(s)
+ case _ => new MutableSetWrapper(s)
}
/**
@@ -172,8 +180,9 @@ trait WrapAsJava {
* @return A Java Set view of the argument.
*/
implicit def setAsJavaSet[A](s: Set[A]): ju.Set[A] = s match {
+ case null => null
case JSetWrapper(wrapped) => wrapped
- case _ => new SetWrapper(s)
+ case _ => new SetWrapper(s)
}
/**
@@ -190,9 +199,9 @@ trait WrapAsJava {
* @return A Java Map view of the argument.
*/
implicit def mutableMapAsJavaMap[A, B](m: mutable.Map[A, B]): ju.Map[A, B] = m match {
- //case JConcurrentMapWrapper(wrapped) => wrapped
+ case null => null
case JMapWrapper(wrapped) => wrapped
- case _ => new MutableMapWrapper(m)
+ case _ => new MutableMapWrapper(m)
}
/**
@@ -210,9 +219,9 @@ trait WrapAsJava {
* @return A Java `Dictionary` view of the argument.
*/
implicit def asJavaDictionary[A, B](m: mutable.Map[A, B]): ju.Dictionary[A, B] = m match {
- //case JConcurrentMapWrapper(wrapped) => wrapped
- case JDictionaryWrapper(wrapped) => wrapped
- case _ => new DictionaryWrapper(m)
+ case null => null
+ case JDictionaryWrapper(wrapped) => wrapped
+ case _ => new DictionaryWrapper(m)
}
/**
@@ -230,9 +239,9 @@ trait WrapAsJava {
* @return A Java `Map` view of the argument.
*/
implicit def mapAsJavaMap[A, B](m: Map[A, B]): ju.Map[A, B] = m match {
- //case JConcurrentMapWrapper(wrapped) => wrapped
+ case null => null
case JMapWrapper(wrapped) => wrapped.asInstanceOf[ju.Map[A, B]]
- case _ => new MapWrapper(m)
+ case _ => new MapWrapper(m)
}
/**
@@ -251,8 +260,9 @@ trait WrapAsJava {
* @return A Java `ConcurrentMap` view of the argument.
*/
implicit def mapAsJavaConcurrentMap[A, B](m: concurrent.Map[A, B]): juc.ConcurrentMap[A, B] = m match {
+ case null => null
case JConcurrentMapWrapper(wrapped) => wrapped
- case _ => new ConcurrentMapWrapper(m)
+ case _ => new ConcurrentMapWrapper(m)
}
}
diff --git a/src/library/scala/collection/convert/WrapAsScala.scala b/src/library/scala/collection/convert/WrapAsScala.scala
index ab151a6778..7332b71af1 100644
--- a/src/library/scala/collection/convert/WrapAsScala.scala
+++ b/src/library/scala/collection/convert/WrapAsScala.scala
@@ -30,8 +30,9 @@ trait WrapAsScala {
* @return A Scala `Iterator` view of the argument.
*/
implicit def asScalaIterator[A](it: ju.Iterator[A]): Iterator[A] = it match {
+ case null => null
case IteratorWrapper(wrapped) => wrapped
- case _ => JIteratorWrapper(it)
+ case _ => JIteratorWrapper(it)
}
/**
@@ -48,8 +49,9 @@ trait WrapAsScala {
* @return A Scala Iterator view of the argument.
*/
implicit def enumerationAsScalaIterator[A](i: ju.Enumeration[A]): Iterator[A] = i match {
+ case null => null
case IteratorWrapper(wrapped) => wrapped
- case _ => JEnumerationWrapper(i)
+ case _ => JEnumerationWrapper(i)
}
/**
@@ -67,8 +69,9 @@ trait WrapAsScala {
* @return A Scala Iterable view of the argument.
*/
implicit def iterableAsScalaIterable[A](i: jl.Iterable[A]): Iterable[A] = i match {
+ case null => null
case IterableWrapper(wrapped) => wrapped
- case _ => JIterableWrapper(i)
+ case _ => JIterableWrapper(i)
}
/**
@@ -82,8 +85,9 @@ trait WrapAsScala {
* @return A Scala Iterable view of the argument.
*/
implicit def collectionAsScalaIterable[A](i: ju.Collection[A]): Iterable[A] = i match {
+ case null => null
case IterableWrapper(wrapped) => wrapped
- case _ => JCollectionWrapper(i)
+ case _ => JCollectionWrapper(i)
}
/**
@@ -101,8 +105,9 @@ trait WrapAsScala {
* @return A Scala mutable `Buffer` view of the argument.
*/
implicit def asScalaBuffer[A](l: ju.List[A]): mutable.Buffer[A] = l match {
- case MutableBufferWrapper(wrapped) => wrapped
- case _ =>new JListWrapper(l)
+ case null => null
+ case MutableBufferWrapper(wrapped) => wrapped
+ case _ => new JListWrapper(l)
}
/**
@@ -119,8 +124,9 @@ trait WrapAsScala {
* @return A Scala mutable Set view of the argument.
*/
implicit def asScalaSet[A](s: ju.Set[A]): mutable.Set[A] = s match {
+ case null => null
case MutableSetWrapper(wrapped) => wrapped
- case _ =>new JSetWrapper(s)
+ case _ => new JSetWrapper(s)
}
/**
@@ -144,9 +150,9 @@ trait WrapAsScala {
* @return A Scala mutable Map view of the argument.
*/
implicit def mapAsScalaMap[A, B](m: ju.Map[A, B]): mutable.Map[A, B] = m match {
- //case ConcurrentMapWrapper(wrapped) => wrapped
+ case null => null
case MutableMapWrapper(wrapped) => wrapped
- case _ => new JMapWrapper(m)
+ case _ => new JMapWrapper(m)
}
/**
@@ -163,8 +169,9 @@ trait WrapAsScala {
* @return A Scala mutable ConcurrentMap view of the argument.
*/
implicit def mapAsScalaConcurrentMap[A, B](m: juc.ConcurrentMap[A, B]): concurrent.Map[A, B] = m match {
- case cmw: ConcurrentMapWrapper[a, b] => cmw.underlying
- case _ => new JConcurrentMapWrapper(m)
+ case null => null
+ case cmw: ConcurrentMapWrapper[A, B] => cmw.underlying
+ case _ => new JConcurrentMapWrapper(m)
}
/**
@@ -179,8 +186,9 @@ trait WrapAsScala {
* @return A Scala mutable Map[String, String] view of the argument.
*/
implicit def dictionaryAsScalaMap[A, B](p: ju.Dictionary[A, B]): mutable.Map[A, B] = p match {
+ case null => null
case DictionaryWrapper(wrapped) => wrapped
- case _ => new JDictionaryWrapper(p)
+ case _ => new JDictionaryWrapper(p)
}
/**
@@ -194,7 +202,8 @@ trait WrapAsScala {
* @return A Scala mutable Map[String, String] view of the argument.
*/
implicit def propertiesAsScalaMap(p: ju.Properties): mutable.Map[String, String] = p match {
- case _ => new JPropertiesWrapper(p)
+ case null => null
+ case _ => new JPropertiesWrapper(p)
}
}
diff --git a/src/library/scala/collection/immutable/HashSet.scala b/src/library/scala/collection/immutable/HashSet.scala
index f548eac88d..49b4397cf2 100644
--- a/src/library/scala/collection/immutable/HashSet.scala
+++ b/src/library/scala/collection/immutable/HashSet.scala
@@ -194,7 +194,7 @@ class HashSet[A] extends AbstractSet[A]
protected def get0(key: A, hash: Int, level: Int): Boolean = false
- def updated0(key: A, hash: Int, level: Int): HashSet[A] =
+ private[collection] def updated0(key: A, hash: Int, level: Int): HashSet[A] =
new HashSet.HashSet1(key, hash)
protected def removed0(key: A, hash: Int, level: Int): HashSet[A] = this
@@ -256,10 +256,10 @@ object HashSet extends ImmutableSetFactory[HashSet] {
class HashSet1[A](private[HashSet] val key: A, private[HashSet] val hash: Int) extends LeafHashSet[A] {
override def size = 1
- override def get0(key: A, hash: Int, level: Int): Boolean =
+ override protected def get0(key: A, hash: Int, level: Int): Boolean =
(hash == this.hash && key == this.key)
- override def subsetOf0(that: HashSet[A], level: Int) = {
+ override protected def subsetOf0(that: HashSet[A], level: Int) = {
// check if that contains this.key
// we use get0 with our key and hash at the correct level instead of calling contains,
// which would not work since that might not be a top-level HashSet
@@ -267,7 +267,7 @@ object HashSet extends ImmutableSetFactory[HashSet] {
that.get0(key, hash, level)
}
- override def updated0(key: A, hash: Int, level: Int): HashSet[A] =
+ override private[collection] def updated0(key: A, hash: Int, level: Int): HashSet[A] =
if (hash == this.hash && key == this.key) this
else {
if (hash != this.hash) {
@@ -312,7 +312,7 @@ object HashSet extends ImmutableSetFactory[HashSet] {
override private[immutable] def diff0(that: HashSet[A], level: Int, buffer: Array[HashSet[A]], offset0: Int): HashSet[A] =
if (that.get0(key, hash, level)) null else this
- override def removed0(key: A, hash: Int, level: Int): HashSet[A] =
+ override protected def removed0(key: A, hash: Int, level: Int): HashSet[A] =
if (hash == this.hash && key == this.key) null else this
override protected def filter0(p: A => Boolean, negate: Boolean, level: Int, buffer: Array[HashSet[A]], offset0: Int): HashSet[A] =
@@ -326,10 +326,10 @@ object HashSet extends ImmutableSetFactory[HashSet] {
override def size = ks.size
- override def get0(key: A, hash: Int, level: Int): Boolean =
+ override protected def get0(key: A, hash: Int, level: Int): Boolean =
if (hash == this.hash) ks.contains(key) else false
- override def subsetOf0(that: HashSet[A], level: Int) = {
+ override protected def subsetOf0(that: HashSet[A], level: Int) = {
// we have to check each element
// we use get0 with our hash at the correct level instead of calling contains,
// which would not work since that might not be a top-level HashSet
@@ -337,11 +337,11 @@ object HashSet extends ImmutableSetFactory[HashSet] {
ks.forall(key => that.get0(key, hash, level))
}
- override def updated0(key: A, hash: Int, level: Int): HashSet[A] =
+ override private[collection] def updated0(key: A, hash: Int, level: Int): HashSet[A] =
if (hash == this.hash) new HashSetCollision1(hash, ks + key)
else makeHashTrieSet(this.hash, this, hash, new HashSet1(key, hash), level)
- override def union0(that: LeafHashSet[A], level: Int): HashSet[A] = that match {
+ override private[immutable] def union0(that: LeafHashSet[A], level: Int): HashSet[A] = that match {
case that if that.hash != this.hash =>
// different hash code, so there is no need to investigate further.
// Just create a branch node containing the two.
@@ -374,7 +374,7 @@ object HashSet extends ImmutableSetFactory[HashSet] {
}
}
- override def union0(that: HashSet[A], level: Int, buffer: Array[HashSet[A]], offset0: Int): HashSet[A] = that match {
+ override private[immutable] def union0(that: HashSet[A], level: Int, buffer: Array[HashSet[A]], offset0: Int): HashSet[A] = that match {
case that: LeafHashSet[A] =>
// switch to the simpler Tree/Leaf implementation
this.union0(that, level)
@@ -431,7 +431,7 @@ object HashSet extends ImmutableSetFactory[HashSet] {
}
}
- override def removed0(key: A, hash: Int, level: Int): HashSet[A] =
+ override protected def removed0(key: A, hash: Int, level: Int): HashSet[A] =
if (hash == this.hash) {
val ks1 = ks - key
ks1.size match {
@@ -528,7 +528,7 @@ object HashSet extends ImmutableSetFactory[HashSet] {
override def size = size0
- override def get0(key: A, hash: Int, level: Int): Boolean = {
+ override protected def get0(key: A, hash: Int, level: Int): Boolean = {
val index = (hash >>> level) & 0x1f
val mask = (1 << index)
if (bitmap == - 1) {
@@ -540,7 +540,7 @@ object HashSet extends ImmutableSetFactory[HashSet] {
false
}
- override def updated0(key: A, hash: Int, level: Int): HashSet[A] = {
+ override private[collection] def updated0(key: A, hash: Int, level: Int): HashSet[A] = {
val index = (hash >>> level) & 0x1f
val mask = (1 << index)
val offset = Integer.bitCount(bitmap & (mask-1))
@@ -842,7 +842,7 @@ object HashSet extends ImmutableSetFactory[HashSet] {
case _ => this
}
- override def removed0(key: A, hash: Int, level: Int): HashSet[A] = {
+ override protected def removed0(key: A, hash: Int, level: Int): HashSet[A] = {
val index = (hash >>> level) & 0x1f
val mask = (1 << index)
val offset = Integer.bitCount(bitmap & (mask-1))
@@ -879,7 +879,7 @@ object HashSet extends ImmutableSetFactory[HashSet] {
}
}
- override def subsetOf0(that: HashSet[A], level: Int): Boolean = if (that eq this) true else that match {
+ override protected def subsetOf0(that: HashSet[A], level: Int): Boolean = if (that eq this) true else that match {
case that: HashTrieSet[A] if this.size0 <= that.size0 =>
// create local mutable copies of members
var abm = this.bitmap
diff --git a/src/library/scala/collection/immutable/List.scala b/src/library/scala/collection/immutable/List.scala
index 82e38d3549..7b1997252d 100644
--- a/src/library/scala/collection/immutable/List.scala
+++ b/src/library/scala/collection/immutable/List.scala
@@ -13,7 +13,7 @@ package immutable
import generic._
import mutable.{Builder, ListBuffer}
import scala.annotation.tailrec
-import java.io._
+import java.io.{ObjectOutputStream, ObjectInputStream}
/** A class for immutable linked lists representing ordered collections
* of elements of type.
@@ -86,7 +86,7 @@ sealed abstract class List[+A] extends AbstractSeq[A]
with Product
with GenericTraversableTemplate[A, List]
with LinearSeqOptimized[A, List[A]]
- with Serializable {
+ with scala.Serializable {
override def companion: GenericCompanion[List] = List
import scala.collection.{Iterable, Traversable, Seq, IndexedSeq}
diff --git a/src/library/scala/collection/immutable/ListMap.scala b/src/library/scala/collection/immutable/ListMap.scala
index 7c40e84280..c5773338f5 100644
--- a/src/library/scala/collection/immutable/ListMap.scala
+++ b/src/library/scala/collection/immutable/ListMap.scala
@@ -29,7 +29,11 @@ object ListMap extends ImmutableMapFactory[ListMap] {
new MapCanBuildFrom[A, B]
def empty[A, B]: ListMap[A, B] = EmptyListMap.asInstanceOf[ListMap[A, B]]
- private object EmptyListMap extends ListMap[Any, Nothing] { }
+ @SerialVersionUID(-8256686706655863282L)
+ private object EmptyListMap extends ListMap[Any, Nothing] {
+ override def apply(key: Any) = throw new NoSuchElementException("key not found: " + key)
+ override def contains(key: Any) = false
+ }
}
/** This class implements immutable maps using a list-based data structure.
@@ -159,7 +163,6 @@ extends AbstractMap[A, B]
*/
override def apply(k: A): B1 = apply0(this, k)
-
@tailrec private def apply0(cur: ListMap[A, B1], k: A): B1 =
if (cur.isEmpty) throw new NoSuchElementException("key not found: "+k)
else if (k == cur.key) cur.value
@@ -176,7 +179,16 @@ extends AbstractMap[A, B]
@tailrec private def get0(cur: ListMap[A, B1], k: A): Option[B1] =
if (k == cur.key) Some(cur.value)
else if (cur.next.nonEmpty) get0(cur.next, k) else None
-
+
+
+ override def contains(key: A): Boolean = contains0(this, key)
+
+ @tailrec private def contains0(cur: ListMap[A, B1], k: A): Boolean =
+ if (k == cur.key) true
+ else if (cur.next.nonEmpty) contains0(cur.next, k)
+ else false
+
+
/** This method allows one to create a new map with an additional mapping
* from `key` to `value`. If the map contains already a mapping for `key`,
* it will be overridden by this function.
@@ -186,6 +198,7 @@ extends AbstractMap[A, B]
new m.Node[B2](k, v)
}
+
/** Creates a new mapping without the given `key`.
* If the map does not contain a mapping for the given key, the
* method returns the same map.
diff --git a/src/library/scala/collection/immutable/Map.scala b/src/library/scala/collection/immutable/Map.scala
index 5178d5a862..63ddcb18cf 100644
--- a/src/library/scala/collection/immutable/Map.scala
+++ b/src/library/scala/collection/immutable/Map.scala
@@ -94,6 +94,8 @@ object Map extends ImmutableMapFactory[Map] {
private object EmptyMap extends AbstractMap[Any, Nothing] with Map[Any, Nothing] with Serializable {
override def size: Int = 0
+ override def apply(key: Any) = throw new NoSuchElementException("key not found: " + key)
+ override def contains(key: Any) = false
def get(key: Any): Option[Nothing] = None
def iterator: Iterator[(Any, Nothing)] = Iterator.empty
override def updated [B1] (key: Any, value: B1): Map[Any, B1] = new Map1(key, value)
@@ -103,6 +105,8 @@ object Map extends ImmutableMapFactory[Map] {
class Map1[A, +B](key1: A, value1: B) extends AbstractMap[A, B] with Map[A, B] with Serializable {
override def size = 1
+ override def apply(key: A) = if (key == key1) value1 else throw new NoSuchElementException("key not found: " + key)
+ override def contains(key: A) = key == key1
def get(key: A): Option[B] =
if (key == key1) Some(value1) else None
def iterator = Iterator((key1, value1))
@@ -119,6 +123,11 @@ object Map extends ImmutableMapFactory[Map] {
class Map2[A, +B](key1: A, value1: B, key2: A, value2: B) extends AbstractMap[A, B] with Map[A, B] with Serializable {
override def size = 2
+ override def apply(key: A) =
+ if (key == key1) value1
+ else if (key == key2) value2
+ else throw new NoSuchElementException("key not found: " + key)
+ override def contains(key: A) = (key == key1) || (key == key2)
def get(key: A): Option[B] =
if (key == key1) Some(value1)
else if (key == key2) Some(value2)
@@ -140,6 +149,12 @@ object Map extends ImmutableMapFactory[Map] {
class Map3[A, +B](key1: A, value1: B, key2: A, value2: B, key3: A, value3: B) extends AbstractMap[A, B] with Map[A, B] with Serializable {
override def size = 3
+ override def apply(key: A) =
+ if (key == key1) value1
+ else if (key == key2) value2
+ else if (key == key3) value3
+ else throw new NoSuchElementException("key not found: " + key)
+ override def contains(key: A) = (key == key1) || (key == key2) || (key == key3)
def get(key: A): Option[B] =
if (key == key1) Some(value1)
else if (key == key2) Some(value2)
@@ -164,6 +179,13 @@ object Map extends ImmutableMapFactory[Map] {
class Map4[A, +B](key1: A, value1: B, key2: A, value2: B, key3: A, value3: B, key4: A, value4: B) extends AbstractMap[A, B] with Map[A, B] with Serializable {
override def size = 4
+ override def apply(key: A) =
+ if (key == key1) value1
+ else if (key == key2) value2
+ else if (key == key3) value3
+ else if (key == key4) value4
+ else throw new NoSuchElementException("key not found: " + key)
+ override def contains(key: A) = (key == key1) || (key == key2) || (key == key3) || (key == key4)
def get(key: A): Option[B] =
if (key == key1) Some(value1)
else if (key == key2) Some(value2)
diff --git a/src/library/scala/collection/immutable/PagedSeq.scala b/src/library/scala/collection/immutable/PagedSeq.scala
index f11217d26a..8910ee16b9 100644
--- a/src/library/scala/collection/immutable/PagedSeq.scala
+++ b/src/library/scala/collection/immutable/PagedSeq.scala
@@ -12,7 +12,7 @@ package scala
package collection
package immutable
-import java.io._
+import java.io.{File, FileReader, Reader}
import scala.util.matching.Regex
import scala.reflect.ClassTag
diff --git a/src/library/scala/collection/immutable/Range.scala b/src/library/scala/collection/immutable/Range.scala
index 3ae8a2c342..0b380517f8 100644
--- a/src/library/scala/collection/immutable/Range.scala
+++ b/src/library/scala/collection/immutable/Range.scala
@@ -202,7 +202,24 @@ extends scala.collection.AbstractSeq[Int]
copy(locationAfterN(n), end, step)
}
)
-
+
+ /** Creates a new range containing the elements starting at `from` up to but not including `until`.
+ *
+ * $doesNotUseBuilders
+ *
+ * @param from the element at which to start
+ * @param until the element at which to end (not included in the range)
+ * @return a new range consisting of a contiguous interval of values in the old range
+ */
+ override def slice(from: Int, until: Int): Range =
+ if (from <= 0) take(until)
+ else if (until >= numRangeElements && numRangeElements >= 0) drop(from)
+ else {
+ val fromValue = locationAfterN(from)
+ if (from >= until) newEmptyRange(fromValue)
+ else new Range.Inclusive(fromValue, locationAfterN(until-1), step)
+ }
+
/** Creates a new range containing all the elements of this range except the last one.
*
* $doesNotUseBuilders
diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala
index 17cf02cce6..6c5b10e73b 100644
--- a/src/library/scala/collection/immutable/Stream.scala
+++ b/src/library/scala/collection/immutable/Stream.scala
@@ -499,6 +499,16 @@ self =>
)
else super.flatMap(f)(bf)
+ override private[scala] def filterImpl(p: A => Boolean, isFlipped: Boolean): Stream[A] = {
+ // optimization: drop leading prefix of elems for which f returns false
+ // var rest = this dropWhile (!p(_)) - forget DRY principle - GC can't collect otherwise
+ var rest = this
+ while (!rest.isEmpty && p(rest.head) == isFlipped) rest = rest.tail
+ // private utility func to avoid `this` on stack (would be needed for the lazy arg)
+ if (rest.nonEmpty) Stream.filteredTail(rest, p, isFlipped)
+ else Stream.Empty
+ }
+
/** Returns all the elements of this `Stream` that satisfy the predicate `p`
* in a new `Stream` - i.e., it is still a lazy data structure. The order of
* the elements is preserved
@@ -512,67 +522,11 @@ self =>
* // produces
* }}}
*/
- override def filter(p: A => Boolean): Stream[A] = {
- // optimization: drop leading prefix of elems for which f returns false
- // var rest = this dropWhile (!p(_)) - forget DRY principle - GC can't collect otherwise
- var rest = this
- while (!rest.isEmpty && !p(rest.head)) rest = rest.tail
- // private utility func to avoid `this` on stack (would be needed for the lazy arg)
- if (rest.nonEmpty) Stream.filteredTail(rest, p)
- else Stream.Empty
- }
-
- override final def withFilter(p: A => Boolean): StreamWithFilter = new StreamWithFilter(p)
-
- /** A lazier implementation of WithFilter than TraversableLike's.
- */
- final class StreamWithFilter(p: A => Boolean) extends WithFilter(p) {
-
- override def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Stream[A], B, That]): That = {
- def tailMap(coll: Stream[A]): Stream[B] = {
- var head: A = null.asInstanceOf[A]
- var tail: Stream[A] = coll
- while (true) {
- if (tail.isEmpty)
- return Stream.Empty
- head = tail.head
- tail = tail.tail
- if (p(head))
- return cons(f(head), tailMap(tail))
- }
- throw new RuntimeException()
- }
-
- if (isStreamBuilder(bf)) asThat(tailMap(Stream.this))
- else super.map(f)(bf)
- }
+ override def filter(p: A => Boolean): Stream[A] = filterImpl(p, isFlipped = false) // This override is only left in 2.11 because of binary compatibility, see PR #3925
- override def flatMap[B, That](f: A => GenTraversableOnce[B])(implicit bf: CanBuildFrom[Stream[A], B, That]): That = {
- def tailFlatMap(coll: Stream[A]): Stream[B] = {
- var head: A = null.asInstanceOf[A]
- var tail: Stream[A] = coll
- while (true) {
- if (tail.isEmpty)
- return Stream.Empty
- head = tail.head
- tail = tail.tail
- if (p(head))
- return f(head).toStream append tailFlatMap(tail)
- }
- throw new RuntimeException()
- }
-
- if (isStreamBuilder(bf)) asThat(tailFlatMap(Stream.this))
- else super.flatMap(f)(bf)
- }
-
- override def foreach[B](f: A => B) =
- for (x <- self)
- if (p(x)) f(x)
-
- override def withFilter(q: A => Boolean): StreamWithFilter =
- new StreamWithFilter(x => p(x) && q(x))
- }
+ /** A FilterMonadic which allows GC of the head of stream during processing */
+ @noinline // Workaround SI-9137, see https://github.com/scala/scala/pull/4284#issuecomment-73180791
+ override final def withFilter(p: A => Boolean): FilterMonadic[A, Stream[A]] = new Stream.StreamWithFilter(this, p)
/** A lazier Iterator than LinearSeqLike's. */
override def iterator: Iterator[A] = new StreamIterator(self)
@@ -1295,13 +1249,36 @@ object Stream extends SeqFactory[Stream] {
else cons(start, range(start + step, end, step))
}
- private[immutable] def filteredTail[A](stream: Stream[A], p: A => Boolean) = {
- cons(stream.head, stream.tail filter p)
+ private[immutable] def filteredTail[A](stream: Stream[A], p: A => Boolean, isFlipped: Boolean) = {
+ cons(stream.head, stream.tail.filterImpl(p, isFlipped))
}
private[immutable] def collectedTail[A, B, That](head: B, stream: Stream[A], pf: PartialFunction[A, B], bf: CanBuildFrom[Stream[A], B, That]) = {
cons(head, stream.tail.collect(pf)(bf).asInstanceOf[Stream[B]])
}
-}
+ /** An implementation of `FilterMonadic` allowing GC of the filtered-out elements of
+ * the `Stream` as it is processed.
+ *
+ * Because this is not an inner class of `Stream` with a reference to the original
+ * head, it is now possible for GC to collect any leading and filtered-out elements
+ * which do not satisfy the filter, while the tail is still processing (see SI-8990).
+ */
+ private[immutable] final class StreamWithFilter[A](sl: => Stream[A], p: A => Boolean) extends FilterMonadic[A, Stream[A]] {
+ private var s = sl // set to null to allow GC after filtered
+ private lazy val filtered = { val f = s filter p; s = null; f } // don't set to null if throw during filter
+
+ def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Stream[A], B, That]): That =
+ filtered map f
+
+ def flatMap[B, That](f: A => scala.collection.GenTraversableOnce[B])(implicit bf: CanBuildFrom[Stream[A], B, That]): That =
+ filtered flatMap f
+ def foreach[U](f: A => U): Unit =
+ filtered foreach f
+
+ def withFilter(q: A => Boolean): FilterMonadic[A, Stream[A]] =
+ new StreamWithFilter[A](filtered, q)
+ }
+
+}
diff --git a/src/library/scala/collection/immutable/StreamViewLike.scala b/src/library/scala/collection/immutable/StreamViewLike.scala
index c2eb85815d..4d7eaeff2a 100644
--- a/src/library/scala/collection/immutable/StreamViewLike.scala
+++ b/src/library/scala/collection/immutable/StreamViewLike.scala
@@ -53,6 +53,7 @@ extends SeqView[A, Coll]
/** boilerplate */
protected override def newForced[B](xs: => scala.collection.GenSeq[B]): Transformed[B] = new { val forced = xs } with AbstractTransformed[B] with Forced[B]
protected override def newAppended[B >: A](that: scala.collection.GenTraversable[B]): Transformed[B] = new { val rest = that } with AbstractTransformed[B] with Appended[B]
+ protected override def newPrepended[B >: A](that: scala.collection.GenTraversable[B]): Transformed[B] = new { protected[this] val fst = that } with AbstractTransformed[B] with Prepended[B]
protected override def newMapped[B](f: A => B): Transformed[B] = new { val mapping = f } with AbstractTransformed[B] with Mapped[B]
protected override def newFlatMapped[B](f: A => scala.collection.GenTraversableOnce[B]): Transformed[B] = new { val mapping = f } with AbstractTransformed[B] with FlatMapped[B]
protected override def newFiltered(p: A => Boolean): Transformed[A] = new { val pred = p } with AbstractTransformed[A] with Filtered
@@ -67,7 +68,6 @@ extends SeqView[A, Coll]
protected override def newPatched[B >: A](_from: Int, _patch: scala.collection.GenSeq[B], _replaced: Int): Transformed[B] = {
new { val from = _from; val patch = _patch; val replaced = _replaced } with AbstractTransformed[B] with Patched[B]
}
- protected override def newPrepended[B >: A](elem: B): Transformed[B] = new { protected[this] val fst = elem } with AbstractTransformed[B] with Prepended[B]
override def stringPrefix = "StreamView"
}
diff --git a/src/library/scala/collection/mutable/AnyRefMap.scala b/src/library/scala/collection/mutable/AnyRefMap.scala
index fccc9d83e6..ed6ca1939d 100644
--- a/src/library/scala/collection/mutable/AnyRefMap.scala
+++ b/src/library/scala/collection/mutable/AnyRefMap.scala
@@ -335,6 +335,24 @@ extends AbstractMap[K, V]
arm
}
+ override def +[V1 >: V](kv: (K, V1)): AnyRefMap[K, V1] = {
+ val arm = clone().asInstanceOf[AnyRefMap[K, V1]]
+ arm += kv
+ arm
+ }
+
+ override def ++[V1 >: V](xs: GenTraversableOnce[(K, V1)]): AnyRefMap[K, V1] = {
+ val arm = clone().asInstanceOf[AnyRefMap[K, V1]]
+ xs.foreach(kv => arm += kv)
+ arm
+ }
+
+ override def updated[V1 >: V](key: K, value: V1): AnyRefMap[K, V1] = {
+ val arm = clone().asInstanceOf[AnyRefMap[K, V1]]
+ arm += (key, value)
+ arm
+ }
+
private[this] def foreachElement[A,B](elems: Array[AnyRef], f: A => B) {
var i,j = 0
while (i < _hashes.length & j < _size) {
diff --git a/src/library/scala/collection/mutable/ArrayOps.scala b/src/library/scala/collection/mutable/ArrayOps.scala
index 00491ef20e..2bc41b5802 100644
--- a/src/library/scala/collection/mutable/ArrayOps.scala
+++ b/src/library/scala/collection/mutable/ArrayOps.scala
@@ -40,9 +40,8 @@ trait ArrayOps[T] extends Any with ArrayLike[T, Array[T]] with CustomParalleliza
arrayElementClass(repr.getClass)
override def copyToArray[U >: T](xs: Array[U], start: Int, len: Int) {
- var l = math.min(len, repr.length)
- if (xs.length - start < l) l = xs.length - start max 0
- Array.copy(repr, 0, xs, start, l)
+ val l = len min repr.length min (xs.length - start)
+ if (l > 0) Array.copy(repr, 0, xs, start, l)
}
override def toArray[U >: T : ClassTag]: Array[U] = {
diff --git a/src/library/scala/collection/mutable/ArraySeq.scala b/src/library/scala/collection/mutable/ArraySeq.scala
index 577a838315..5a50f4fb27 100644
--- a/src/library/scala/collection/mutable/ArraySeq.scala
+++ b/src/library/scala/collection/mutable/ArraySeq.scala
@@ -87,7 +87,7 @@ extends AbstractSeq[A]
*/
override def copyToArray[B >: A](xs: Array[B], start: Int, len: Int) {
val len1 = len min (xs.length - start) min length
- Array.copy(array, 0, xs, start, len1)
+ if (len1 > 0) Array.copy(array, 0, xs, start, len1)
}
override def clone(): ArraySeq[A] = {
diff --git a/src/library/scala/collection/mutable/BufferLike.scala b/src/library/scala/collection/mutable/BufferLike.scala
index 3c57387c03..8d24538620 100644
--- a/src/library/scala/collection/mutable/BufferLike.scala
+++ b/src/library/scala/collection/mutable/BufferLike.scala
@@ -211,13 +211,6 @@ trait BufferLike[A, +This <: BufferLike[A, This] with Buffer[A]]
*/
override def stringPrefix: String = "Buffer"
- /** Returns the current evolving(!) state of this buffer as a read-only sequence.
- *
- * @return A sequence that forwards to this buffer for all its operations.
- */
- @deprecated("The returned sequence changes as this buffer is mutated. For an immutable copy, use, e.g., toList.", "2.11.0")
- def readOnly: scala.collection.Seq[A] = toSeq
-
/** Creates a new collection containing both the elements of this collection and the provided
* traversable object.
*
diff --git a/src/library/scala/collection/mutable/BufferProxy.scala b/src/library/scala/collection/mutable/BufferProxy.scala
index d9632cce91..2d52831d37 100644
--- a/src/library/scala/collection/mutable/BufferProxy.scala
+++ b/src/library/scala/collection/mutable/BufferProxy.scala
@@ -43,8 +43,6 @@ trait BufferProxy[A] extends Buffer[A] with Proxy {
*/
def +=(elem: A): this.type = { self.+=(elem); this }
- override def readOnly = self.readOnly
-
/** Appends a number of elements provided by a traversable object.
*
* @param xs the traversable object.
diff --git a/src/library/scala/collection/mutable/ListBuffer.scala b/src/library/scala/collection/mutable/ListBuffer.scala
index f9bab40a1e..2bc6738e53 100644
--- a/src/library/scala/collection/mutable/ListBuffer.scala
+++ b/src/library/scala/collection/mutable/ListBuffer.scala
@@ -12,7 +12,7 @@ package mutable
import generic._
import immutable.{List, Nil, ::}
-import java.io._
+import java.io.{ObjectOutputStream, ObjectInputStream}
import scala.annotation.migration
/** A `Buffer` implementation backed by a list. It provides constant time
@@ -408,9 +408,6 @@ final class ListBuffer[A]
}
}
- @deprecated("The result of this method will change along with this buffer, which is often not what's expected.", "2.11.0")
- override def readOnly: List[A] = start
-
// Private methods
/** Copy contents of this buffer */
@@ -426,7 +423,7 @@ final class ListBuffer[A]
}
override def equals(that: Any): Boolean = that match {
- case that: ListBuffer[_] => this.readOnly equals that.readOnly
+ case that: ListBuffer[_] => this.start equals that.start
case _ => super.equals(that)
}
diff --git a/src/library/scala/collection/mutable/LongMap.scala b/src/library/scala/collection/mutable/LongMap.scala
index c124f35cd7..1eb12d817c 100644
--- a/src/library/scala/collection/mutable/LongMap.scala
+++ b/src/library/scala/collection/mutable/LongMap.scala
@@ -415,6 +415,24 @@ extends AbstractMap[Long, V]
lm
}
+ override def +[V1 >: V](kv: (Long, V1)): LongMap[V1] = {
+ val lm = clone().asInstanceOf[LongMap[V1]]
+ lm += kv
+ lm
+ }
+
+ override def ++[V1 >: V](xs: GenTraversableOnce[(Long, V1)]): LongMap[V1] = {
+ val lm = clone().asInstanceOf[LongMap[V1]]
+ xs.foreach(kv => lm += kv)
+ lm
+ }
+
+ override def updated[V1 >: V](key: Long, value: V1): LongMap[V1] = {
+ val lm = clone().asInstanceOf[LongMap[V1]]
+ lm += (key, value)
+ lm
+ }
+
/** Applies a function to all keys of this map. */
def foreachKey[A](f: Long => A) {
if ((extraKeys & 1) == 1) f(0L)
@@ -541,7 +559,7 @@ object LongMap {
/** Creates a new `LongMap` from keys and values.
* Equivalent to but more efficient than `LongMap((keys zip values): _*)`.
*/
- def fromZip[V](keys: Iterable[Long], values: Iterable[V]): LongMap[V] = {
+ def fromZip[V](keys: collection.Iterable[Long], values: collection.Iterable[V]): LongMap[V] = {
val sz = math.min(keys.size, values.size)
val lm = new LongMap[V](sz * 2)
val ki = keys.iterator
diff --git a/src/library/scala/collection/mutable/MapLike.scala b/src/library/scala/collection/mutable/MapLike.scala
index 44af886cf5..949e5e3536 100644
--- a/src/library/scala/collection/mutable/MapLike.scala
+++ b/src/library/scala/collection/mutable/MapLike.scala
@@ -61,6 +61,18 @@ trait MapLike[A, B, +This <: MapLike[A, B, This] with Map[A, B]]
override protected[this] def newBuilder: Builder[(A, B), This] = empty
protected[this] override def parCombiner = ParMap.newCombiner[A, B]
+
+ /** Converts this $coll to a sequence.
+ *
+ * ```Note```: assumes a fast `size` method. Subclasses should override if this is not true.
+ */
+ override def toSeq: collection.Seq[(A, B)] = {
+ // ArrayBuffer for efficiency, preallocated to the right size.
+ val result = new ArrayBuffer[(A, B)](size)
+ foreach(result += _)
+ result
+ }
+
/** Adds a new key/value pair to this map and optionally returns previously bound value.
* If the map already contains a
diff --git a/src/library/scala/collection/mutable/PriorityQueue.scala b/src/library/scala/collection/mutable/PriorityQueue.scala
index d3c4161e3b..619beeb1d6 100644
--- a/src/library/scala/collection/mutable/PriorityQueue.scala
+++ b/src/library/scala/collection/mutable/PriorityQueue.scala
@@ -16,7 +16,7 @@ import generic._
* To prioritize elements of type A there must be an implicit
* Ordering[A] available at creation.
*
- * Only the `dequeue` and `dequeueAll` methods will return methods in priority
+ * Only the `dequeue` and `dequeueAll` methods will return elements in priority
* order (while removing elements from the heap). Standard collection methods
* including `drop` and `iterator` will remove or traverse the heap in whichever
* order seems most convenient.
diff --git a/src/library/scala/collection/mutable/ResizableArray.scala b/src/library/scala/collection/mutable/ResizableArray.scala
index c3047522e2..85a299216e 100644
--- a/src/library/scala/collection/mutable/ResizableArray.scala
+++ b/src/library/scala/collection/mutable/ResizableArray.scala
@@ -74,7 +74,7 @@ trait ResizableArray[A] extends IndexedSeq[A]
*/
override def copyToArray[B >: A](xs: Array[B], start: Int, len: Int) {
val len1 = len min (xs.length - start) min length
- Array.copy(array, 0, xs, start, len1)
+ if (len1 > 0) Array.copy(array, 0, xs, start, len1)
}
//##########################################################################
diff --git a/src/library/scala/collection/mutable/SetLike.scala b/src/library/scala/collection/mutable/SetLike.scala
index 81a71adc91..40a5c93064 100644
--- a/src/library/scala/collection/mutable/SetLike.scala
+++ b/src/library/scala/collection/mutable/SetLike.scala
@@ -72,6 +72,17 @@ trait SetLike[A, +This <: SetLike[A, This] with Set[A]]
protected[this] override def parCombiner = ParSet.newCombiner[A]
+ /** Converts this $coll to a sequence.
+ *
+ * ```Note```: assumes a fast `size` method. Subclasses should override if this is not true.
+ */
+ override def toSeq: collection.Seq[A] = {
+ // ArrayBuffer for efficiency, preallocated to the right size.
+ val result = new ArrayBuffer[A](size)
+ foreach(result += _)
+ result
+ }
+
/** Adds an element to this $coll.
*
* @param elem the element to be added
diff --git a/src/library/scala/collection/parallel/RemainsIterator.scala b/src/library/scala/collection/parallel/RemainsIterator.scala
index 5f2ceac0e0..7bb278b038 100644
--- a/src/library/scala/collection/parallel/RemainsIterator.scala
+++ b/src/library/scala/collection/parallel/RemainsIterator.scala
@@ -456,6 +456,15 @@ self =>
}
it
}
+ /** Drop implemented as simple eager consumption. */
+ override def drop(n: Int): IterableSplitter[T] = {
+ var i = 0
+ while (i < n && hasNext) {
+ next()
+ i += 1
+ }
+ this
+ }
override def take(n: Int): IterableSplitter[T] = newTaken(n)
override def slice(from1: Int, until1: Int): IterableSplitter[T] = newSliceInternal(newTaken(until1), from1)
diff --git a/src/library/scala/collection/parallel/immutable/ParHashSet.scala b/src/library/scala/collection/parallel/immutable/ParHashSet.scala
index 65a632470e..3a1ec7fff8 100644
--- a/src/library/scala/collection/parallel/immutable/ParHashSet.scala
+++ b/src/library/scala/collection/parallel/immutable/ParHashSet.scala
@@ -197,7 +197,7 @@ extends scala.collection.parallel.BucketCombiner[T, ParHashSet[T], Any, HashSetC
while (i < chunksz) {
val v = chunkarr(i).asInstanceOf[T]
val hc = trie.computeHash(v)
- trie = trie.updated0(v, hc, rootbits)
+ trie = trie.updated0(v, hc, rootbits) // internal API, private[collection]
i += 1
}
i = 0
diff --git a/src/library/scala/concurrent/BlockContext.scala b/src/library/scala/concurrent/BlockContext.scala
index 747cc393c3..2b8ed4c7ca 100644
--- a/src/library/scala/concurrent/BlockContext.scala
+++ b/src/library/scala/concurrent/BlockContext.scala
@@ -41,7 +41,7 @@ package scala.concurrent
trait BlockContext {
/** Used internally by the framework;
- * Designates (and eventually executes) a thunk which potentially blocks the calling `Thread`.
+ * Designates (and eventually executes) a thunk which potentially blocks the calling `java.lang.Thread`.
*
* Clients must use `scala.concurrent.blocking` or `scala.concurrent.Await` instead.
*/
@@ -53,9 +53,16 @@ object BlockContext {
override def blockOn[T](thunk: =>T)(implicit permission: CanAwait): T = thunk
}
+ /**
+ * @return the `BlockContext` that will be used if no other is found.
+ **/
+ def defaultBlockContext: BlockContext = DefaultBlockContext
+
private val contextLocal = new ThreadLocal[BlockContext]()
- /** Obtain the current thread's current `BlockContext`. */
+ /**
+ @return the `BlockContext` that would be used for the current `java.lang.Thread` at this point
+ **/
def current: BlockContext = contextLocal.get match {
case null => Thread.currentThread match {
case ctx: BlockContext => ctx
@@ -64,7 +71,9 @@ object BlockContext {
case some => some
}
- /** Pushes a current `BlockContext` while executing `body`. */
+ /**
+ * Installs a current `BlockContext` around executing `body`.
+ **/
def withBlockContext[T](blockContext: BlockContext)(body: => T): T = {
val old = contextLocal.get // can be null
try {
diff --git a/src/library/scala/concurrent/ExecutionContext.scala b/src/library/scala/concurrent/ExecutionContext.scala
index e380c55880..df2d68c9c6 100644
--- a/src/library/scala/concurrent/ExecutionContext.scala
+++ b/src/library/scala/concurrent/ExecutionContext.scala
@@ -72,22 +72,24 @@ trait ExecutionContext {
*/
def reportFailure(@deprecatedName('t) cause: Throwable): Unit
- /** Prepares for the execution of a task. Returns the prepared execution context.
- *
- * `prepare` should be called at the site where an `ExecutionContext` is received (for
- * example, through an implicit method parameter). The returned execution context may
- * then be used to execute tasks. The role of `prepare` is to save any context relevant
- * to an execution's ''call site'', so that this context may be restored at the
- * ''execution site''. (These are often different: for example, execution may be
- * suspended through a `Promise`'s future until the `Promise` is completed, which may
- * be done in another thread, on another stack.)
- *
- * Note: a valid implementation of `prepare` is one that simply returns `this`.
- *
- * @return the prepared execution context
- */
+ /** Prepares for the execution of a task. Returns the prepared
+ * execution context. The recommended implementation of
+ * `prepare` is to return `this`.
+ *
+ * This method should no longer be overridden or called. It was
+ * originally expected that `prepare` would be called by
+ * all libraries that consume ExecutionContexts, in order to
+ * capture thread local context. However, this usage has proven
+ * difficult to implement in practice and instead it is
+ * now better to avoid using `prepare` entirely.
+ *
+ * Instead, if an `ExecutionContext` needs to capture thread
+ * local context, it should capture that context when it is
+ * constructed, so that it doesn't need any additional
+ * preparation later.
+ */
+ @deprecated("Preparation of ExecutionContexts will be removed.", "2.12")
def prepare(): ExecutionContext = this
-
}
/**
@@ -116,7 +118,7 @@ object ExecutionContext {
*
* @return the global `ExecutionContext`
*/
- def global: ExecutionContextExecutor = Implicits.global
+ def global: ExecutionContextExecutor = Implicits.global.asInstanceOf[ExecutionContextExecutor]
object Implicits {
/**
@@ -127,7 +129,7 @@ object ExecutionContext {
* the thread pool uses a target number of worker threads equal to the number of
* [[https://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html#availableProcessors-- available processors]].
*/
- implicit lazy val global: ExecutionContextExecutor = impl.ExecutionContextImpl.fromExecutor(null: Executor)
+ implicit lazy val global: ExecutionContext = impl.ExecutionContextImpl.fromExecutor(null: Executor)
}
/** Creates an `ExecutionContext` from the given `ExecutorService`.
diff --git a/src/library/scala/concurrent/Future.scala b/src/library/scala/concurrent/Future.scala
index 914646320c..6304f35da9 100644
--- a/src/library/scala/concurrent/Future.scala
+++ b/src/library/scala/concurrent/Future.scala
@@ -10,26 +10,22 @@ package scala.concurrent
import scala.language.higherKinds
-import java.util.concurrent.{ ConcurrentLinkedQueue, TimeUnit, Callable }
+import java.util.concurrent.{ CountDownLatch, TimeUnit, Callable }
import java.util.concurrent.TimeUnit.{ NANOSECONDS => NANOS, MILLISECONDS ⇒ MILLIS }
-import java.lang.{ Iterable => JIterable }
-import java.util.{ LinkedList => JLinkedList }
-import java.util.concurrent.atomic.{ AtomicReferenceFieldUpdater, AtomicInteger, AtomicLong, AtomicBoolean }
+import java.util.concurrent.atomic.AtomicInteger
import scala.util.control.NonFatal
-import scala.Option
import scala.util.{Try, Success, Failure}
-
+import scala.concurrent.duration._
import scala.annotation.tailrec
import scala.collection.mutable.Builder
import scala.collection.generic.CanBuildFrom
import scala.reflect.ClassTag
-
/** The trait that represents futures.
*
- * Asynchronous computations that yield futures are created with the `Future` call:
+ * Asynchronous computations that yield futures are created with the `Future.apply` call:
*
* {{{
* val s = "Hello"
@@ -60,6 +56,10 @@ import scala.reflect.ClassTag
* If a future is failed with a `scala.runtime.NonLocalReturnControl`,
* it is completed with a value from that throwable instead.
*
+ * @define swallowsExceptions
+ * Since this method executes asynchronously and does not produce a return value,
+ * any non-fatal exceptions thrown will be reported to the `ExecutionContext`.
+ *
* @define nonDeterministic
* Note: using this method yields nondeterministic dataflow programs.
*
@@ -91,14 +91,7 @@ import scala.reflect.ClassTag
* `execute()` either immediately or asynchronously.
*/
trait Future[+T] extends Awaitable[T] {
-
- // The executor within the lexical scope
- // of the Future trait. Note that this will
- // (modulo bugs) _never_ execute a callback
- // other than those below in this same file.
- //
- // See the documentation on `InternalCallbackExecutor` for more details.
- private def internalExecutor = Future.InternalCallbackExecutor
+ import Future.{ InternalCallbackExecutor => internalExecutor }
/* Callbacks */
@@ -109,9 +102,11 @@ trait Future[+T] extends Awaitable[T] {
* If the future has already been completed with a value,
* this will either be applied immediately or be scheduled asynchronously.
*
+ * $swallowsExceptions
* $multipleCallbacks
* $callbackInContext
*/
+ @deprecated("use `foreach` or `onComplete` instead (keep in mind that they take total rather than partial functions)", "2.12")
def onSuccess[U](pf: PartialFunction[T, U])(implicit executor: ExecutionContext): Unit = onComplete {
case Success(v) =>
pf.applyOrElse[T, Any](v, Predef.conforms[T]) // Exploiting the cached function to avoid MatchError
@@ -128,9 +123,11 @@ trait Future[+T] extends Awaitable[T] {
*
* Will not be called in case that the future is completed with a value.
*
+ * $swallowsExceptions
* $multipleCallbacks
* $callbackInContext
*/
+ @deprecated("use `onComplete` or `failed.foreach` instead (keep in mind that they take total rather than partial functions)", "2.12")
def onFailure[U](@deprecatedName('callback) pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Unit = onComplete {
case Failure(t) =>
pf.applyOrElse[Throwable, Any](t, Predef.conforms[Throwable]) // Exploiting the cached function to avoid MatchError
@@ -143,8 +140,12 @@ trait Future[+T] extends Awaitable[T] {
* If the future has already been completed,
* this will either be applied immediately or be scheduled asynchronously.
*
+ * $swallowsExceptions
* $multipleCallbacks
* $callbackInContext
+ *
+ * @tparam U only used to accept any return type of the given callback function
+ * @param f the function to be executed when this `Future` completes
*/
def onComplete[U](@deprecatedName('func) f: Try[T] => U)(implicit executor: ExecutionContext): Unit
@@ -160,46 +161,47 @@ trait Future[+T] extends Awaitable[T] {
*/
def isCompleted: Boolean
- /** The value of this `Future`.
+ /** The current value of this `Future`.
+ *
+ * $nonDeterministic
*
* If the future is not completed the returned value will be `None`.
* If the future is completed the value will be `Some(Success(t))`
* if it contains a valid result, or `Some(Failure(error))` if it contains
* an exception.
+ *
+ * @return `None` if the `Future` wasn't completed, `Some` if it was.
*/
def value: Option[Try[T]]
/* Projections */
- /** Returns a failed projection of this future.
- *
- * The failed projection is a future holding a value of type `Throwable`.
+ /** The returned `Future` will be successfully completed with the `Throwable` of the original `Future`
+ * if the original `Future` fails.
*
- * It is completed with a value which is the throwable of the original future
- * in case the original future is failed.
+ * If the original `Future` is successful, the returned `Future` is failed with a `NoSuchElementException`.
*
- * It is failed with a `NoSuchElementException` if the original future is completed successfully.
- *
- * Blocking on this future returns a value if the original future is completed with an exception
- * and throws a corresponding exception if the original future fails.
+ * @return a failed projection of this `Future`.
*/
- def failed: Future[Throwable] = {
- implicit val ec = internalExecutor
- val p = Promise[Throwable]()
- onComplete {
- case Failure(t) => p success t
- case Success(v) => p failure (new NoSuchElementException("Future.failed not completed with a throwable."))
- }
- p.future
- }
+ def failed: Future[Throwable] =
+ transform({
+ case Failure(t) => Success(t)
+ case Success(v) => Failure(new NoSuchElementException("Future.failed not completed with a throwable."))
+ })(internalExecutor)
/* Monadic operations */
/** Asynchronously processes the value in the future once the value becomes available.
*
- * Will not be called if the future fails.
+ * WARNING: Will not be called if this future is never completed or if it is completed with a failure.
+ *
+ * $swallowsExceptions
+ *
+ * @tparam U only used to accept any return type of the given callback function
+ * @param f the function which will be executed if this `Future` completes with a result,
+ * the return value of `f` will be discarded.
*/
def foreach[U](f: T => U)(implicit executor: ExecutionContext): Unit = onComplete { _ foreach f }
@@ -208,33 +210,49 @@ trait Future[+T] extends Awaitable[T] {
* exception thrown when 's' or 'f' is applied, that exception will be propagated
* to the resulting future.
*
- * @param s function that transforms a successful result of the receiver into a
- * successful result of the returned future
- * @param f function that transforms a failure of the receiver into a failure of
- * the returned future
- * @return a future that will be completed with the transformed value
- */
- def transform[S](s: T => S, f: Throwable => Throwable)(implicit executor: ExecutionContext): Future[S] = {
- val p = Promise[S]()
- // transform on Try has the wrong shape for us here
- onComplete {
- case Success(r) => p complete Try(s(r))
- case Failure(t) => p complete Try(throw f(t)) // will throw fatal errors!
+ * @tparam S the type of the returned `Future`
+ * @param s function that transforms a successful result of the receiver into a successful result of the returned future
+ * @param f function that transforms a failure of the receiver into a failure of the returned future
+ * @return a `Future` that will be completed with the transformed value
+ */
+ def transform[S](s: T => S, f: Throwable => Throwable)(implicit executor: ExecutionContext): Future[S] =
+ transform {
+ case Success(r) => Try(s(r))
+ case Failure(t) => Try(throw f(t)) // will throw fatal errors!
}
- p.future
- }
+
+ /** Creates a new Future by applying the specified function to the result
+ * of this Future. If there is any non-fatal exception thrown when 'f'
+ * is applied then that exception will be propagated to the resulting future.
+ *
+ * @tparam S the type of the returned `Future`
+ * @param f function that transforms the result of this future
+ * @return a `Future` that will be completed with the transformed value
+ */
+ def transform[S](f: Try[T] => Try[S])(implicit executor: ExecutionContext): Future[S]
+
+ /** Creates a new Future by applying the specified function, which produces a Future, to the result
+ * of this Future. If there is any non-fatal exception thrown when 'f'
+ * is applied then that exception will be propagated to the resulting future.
+ *
+ * @tparam S the type of the returned `Future`
+ * @param f function that transforms the result of this future
+ * @return a `Future` that will be completed with the transformed value
+ */
+ def transformWith[S](f: Try[T] => Future[S])(implicit executor: ExecutionContext): Future[S]
+
/** Creates a new future by applying a function to the successful result of
* this future. If this future is completed with an exception then the new
* future will also contain this exception.
*
* $forComprehensionExamples
+ *
+ * @tparam S the type of the returned `Future`
+ * @param f the function which will be applied to the successful result of this `Future`
+ * @return a `Future` which will be completed with the result of the application of the function
*/
- def map[S](f: T => S)(implicit executor: ExecutionContext): Future[S] = { // transform(f, identity)
- val p = Promise[S]()
- onComplete { v => p complete (v map f) }
- p.future
- }
+ def map[S](f: T => S)(implicit executor: ExecutionContext): Future[S] = transform(_.map(f))
/** Creates a new future by applying a function to the successful result of
* this future, and returns the result of the function as the new future.
@@ -242,21 +260,23 @@ trait Future[+T] extends Awaitable[T] {
* also contain this exception.
*
* $forComprehensionExamples
+ *
+ * @tparam S the type of the returned `Future`
+ * @param f the function which will be applied to the successful result of this `Future`
+ * @return a `Future` which will be completed with the result of the application of the function
*/
- def flatMap[S](f: T => Future[S])(implicit executor: ExecutionContext): Future[S] = {
- import impl.Promise.DefaultPromise
- val p = new DefaultPromise[S]()
- onComplete {
- case f: Failure[_] => p complete f.asInstanceOf[Failure[S]]
- case Success(v) => try f(v) match {
- // If possible, link DefaultPromises to avoid space leaks
- case dp: DefaultPromise[_] => dp.asInstanceOf[DefaultPromise[S]].linkRootOf(p)
- case fut => fut.onComplete(p.complete)(internalExecutor)
- } catch { case NonFatal(t) => p failure t }
- }
- p.future
+ def flatMap[S](f: T => Future[S])(implicit executor: ExecutionContext): Future[S] = transformWith {
+ case Success(s) => f(s)
+ case Failure(_) => this.asInstanceOf[Future[S]]
}
+ /** Creates a new future with one level of nesting flattened, this method is equivalent
+ * to `flatMap(identity)`.
+ *
+ * @tparam S the type of the returned `Future`
+ */
+ def flatten[S](implicit ev: T <:< Future[S]): Future[S] = flatMap(ev)(internalExecutor)
+
/** Creates a new future by filtering the value of the current future with a predicate.
*
* If the current future contains a value which satisfies the predicate, the new future will also hold that value.
@@ -269,14 +289,15 @@ trait Future[+T] extends Awaitable[T] {
* val f = Future { 5 }
* val g = f filter { _ % 2 == 1 }
* val h = f filter { _ % 2 == 0 }
- * Await.result(g, Duration.Zero) // evaluates to 5
+ * g foreach println // Eventually prints 5
* Await.result(h, Duration.Zero) // throw a NoSuchElementException
* }}}
+ *
+ * @param p the predicate to apply to the successful result of this `Future`
+ * @return a `Future` which will hold the successful result of this `Future` if it matches the predicate or a `NoSuchElementException`
*/
def filter(@deprecatedName('pred) p: T => Boolean)(implicit executor: ExecutionContext): Future[T] =
- map {
- r => if (p(r)) r else throw new NoSuchElementException("Future.filter predicate is not satisfied")
- }
+ map { r => if (p(r)) r else throw new NoSuchElementException("Future.filter predicate is not satisfied") }
/** Used by for-comprehensions.
*/
@@ -298,9 +319,13 @@ trait Future[+T] extends Awaitable[T] {
* val h = f collect {
* case x if x > 0 => x * 2
* }
- * Await.result(g, Duration.Zero) // evaluates to 5
+ * g foreach println // Eventually prints 5
* Await.result(h, Duration.Zero) // throw a NoSuchElementException
* }}}
+ *
+ * @tparam S the type of the returned `Future`
+ *  @param pf the `PartialFunction` to apply to the successful result of this `Future`
+ * @return a `Future` holding the result of application of the `PartialFunction` or a `NoSuchElementException`
*/
def collect[S](pf: PartialFunction[T, S])(implicit executor: ExecutionContext): Future[S] =
map {
@@ -318,12 +343,13 @@ trait Future[+T] extends Awaitable[T] {
* Future (6 / 0) recover { case e: NotFoundException => 0 } // result: exception
* Future (6 / 2) recover { case e: ArithmeticException => 0 } // result: 3
* }}}
+ *
+ * @tparam U the type of the returned `Future`
+ * @param pf the `PartialFunction` to apply if this `Future` fails
+ * @return a `Future` with the successful value of this `Future` or the result of the `PartialFunction`
*/
- def recover[U >: T](pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Future[U] = {
- val p = Promise[U]()
- onComplete { v => p complete (v recover pf) }
- p.future
- }
+ def recover[U >: T](pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Future[U] =
+ transform { _ recover pf }
/** Creates a new future that will handle any matching throwable that this
* future might contain by assigning it a value of another future.
@@ -337,15 +363,16 @@ trait Future[+T] extends Awaitable[T] {
* val f = Future { Int.MaxValue }
* Future (6 / 0) recoverWith { case e: ArithmeticException => f } // result: Int.MaxValue
* }}}
+ *
+ * @tparam U the type of the returned `Future`
+ * @param pf the `PartialFunction` to apply if this `Future` fails
+ * @return a `Future` with the successful value of this `Future` or the outcome of the `Future` returned by the `PartialFunction`
*/
- def recoverWith[U >: T](pf: PartialFunction[Throwable, Future[U]])(implicit executor: ExecutionContext): Future[U] = {
- val p = Promise[U]()
- onComplete {
- case Failure(t) => try pf.applyOrElse(t, (_: Throwable) => this).onComplete(p.complete)(internalExecutor) catch { case NonFatal(t) => p failure t }
- case other => p complete other
+ def recoverWith[U >: T](pf: PartialFunction[Throwable, Future[U]])(implicit executor: ExecutionContext): Future[U] =
+ transformWith {
+ case Failure(t) => pf.applyOrElse(t, (_: Throwable) => this)
+ case Success(_) => this
}
- p.future
- }
/** Zips the values of `this` and `that` future, and creates
* a new future holding the tuple of their results.
@@ -354,17 +381,35 @@ trait Future[+T] extends Awaitable[T] {
* with the throwable stored in `this`.
* Otherwise, if `that` future fails, the resulting future is failed
* with the throwable stored in `that`.
+ *
+ * @tparam U the type of the other `Future`
+ * @param that the other `Future`
+ * @return a `Future` with the results of both futures or the failure of the first of them that failed
*/
def zip[U](that: Future[U]): Future[(T, U)] = {
implicit val ec = internalExecutor
- val p = Promise[(T, U)]()
- onComplete {
- case f: Failure[_] => p complete f.asInstanceOf[Failure[(T, U)]]
- case Success(s) => that onComplete { c => p.complete(c map { s2 => (s, s2) }) }
- }
- p.future
+ flatMap { r1 => that.map(r2 => (r1, r2)) }
}
+ /** Zips the values of `this` and `that` future using a function `f`,
+ * and creates a new future holding the result.
+ *
+ * If `this` future fails, the resulting future is failed
+ * with the throwable stored in `this`.
+ * Otherwise, if `that` future fails, the resulting future is failed
+ * with the throwable stored in `that`.
+ * If the application of `f` throws a throwable, the resulting future
+ * is failed with that throwable if it is non-fatal.
+ *
+ * @tparam U the type of the other `Future`
+ * @tparam R the type of the resulting `Future`
+ * @param that the other `Future`
+ * @param f the function to apply to the results of `this` and `that`
+ * @return a `Future` with the result of the application of `f` to the results of `this` and `that`
+ */
+ def zipWith[U, R](that: Future[U])(f: (T, U) => R)(implicit executor: ExecutionContext): Future[R] =
+ flatMap(r1 => that.map(r2 => f(r1, r2)))(internalExecutor)
+
/** Creates a new future which holds the result of this future if it was completed successfully, or, if not,
* the result of the `that` future if `that` is completed successfully.
* If both futures are failed, the resulting future holds the throwable object of the first future.
@@ -376,24 +421,26 @@ trait Future[+T] extends Awaitable[T] {
* val f = Future { sys.error("failed") }
* val g = Future { 5 }
* val h = f fallbackTo g
- * Await.result(h, Duration.Zero) // evaluates to 5
+ * h foreach println // Eventually prints 5
* }}}
+ *
+ * @tparam U the type of the other `Future` and the resulting `Future`
+ * @param that the `Future` whose result we want to use if this `Future` fails.
+ * @return a `Future` with the successful result of this or that `Future` or the failure of this `Future` if both fail
*/
- def fallbackTo[U >: T](that: Future[U]): Future[U] = {
- implicit val ec = internalExecutor
- val p = Promise[U]()
- onComplete {
- case s @ Success(_) => p complete s
- case f @ Failure(_) => that onComplete {
- case s2 @ Success(_) => p complete s2
- case _ => p complete f // Use the first failure as the failure
- }
+ def fallbackTo[U >: T](that: Future[U]): Future[U] =
+ if (this eq that) this
+ else {
+ implicit val ec = internalExecutor
+ recoverWith { case _ => that } recoverWith { case _ => this }
}
- p.future
- }
/** Creates a new `Future[S]` which is completed with this `Future`'s result if
* that conforms to `S`'s erased type or a `ClassCastException` otherwise.
+ *
+ * @tparam S the type of the returned `Future`
+ * @param tag the `ClassTag` which will be used to cast the result of this `Future`
+ * @return a `Future` holding the casted result of this `Future` or a `ClassCastException` otherwise
*/
def mapTo[S](implicit tag: ClassTag[S]): Future[S] = {
implicit val ec = internalExecutor
@@ -427,15 +474,19 @@ trait Future[+T] extends Awaitable[T] {
* case Success(v) => println(v)
* }
* }}}
+ *
+ * @tparam U only used to accept any return type of the given `PartialFunction`
+ * @param pf a `PartialFunction` which will be conditionally applied to the outcome of this `Future`
+ * @return a `Future` which will be completed with the exact same outcome as this `Future` but after the `PartialFunction` has been executed.
*/
- def andThen[U](pf: PartialFunction[Try[T], U])(implicit executor: ExecutionContext): Future[T] = {
- val p = Promise[T]()
- onComplete {
- case r => try pf.applyOrElse[Try[T], Any](r, Predef.conforms[Try[T]]) finally p complete r
- }
- p.future
- }
+ def andThen[U](pf: PartialFunction[Try[T], U])(implicit executor: ExecutionContext): Future[T] =
+ transform {
+ result =>
+ try pf.applyOrElse[Try[T], Any](result, Predef.conforms[Try[T]])
+ catch { case NonFatal(t) => executor reportFailure t }
+ result
+ }
}
@@ -459,40 +510,102 @@ object Future {
classOf[Unit] -> classOf[scala.runtime.BoxedUnit]
)
+ /** A Future which is never completed.
+ */
+ final object never extends Future[Nothing] {
+
+ @throws(classOf[TimeoutException])
+ @throws(classOf[InterruptedException])
+ override def ready(atMost: Duration)(implicit permit: CanAwait): this.type = {
+ atMost match {
+ case e if e eq Duration.Undefined => throw new IllegalArgumentException("cannot wait for Undefined period")
+ case Duration.Inf => new CountDownLatch(1).await()
+ case Duration.MinusInf => // Drop out
+ case f: FiniteDuration =>
+ if (f > Duration.Zero) new CountDownLatch(1).await(f.toNanos, TimeUnit.NANOSECONDS)
+ }
+ throw new TimeoutException(s"Future timed out after [$atMost]")
+ }
+
+ @throws(classOf[Exception])
+ override def result(atMost: Duration)(implicit permit: CanAwait): Nothing = {
+ ready(atMost)
+ throw new TimeoutException(s"Future timed out after [$atMost]")
+ }
+
+ override def onSuccess[U](pf: PartialFunction[Nothing, U])(implicit executor: ExecutionContext): Unit = ()
+ override def onFailure[U](pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Unit = ()
+ override def onComplete[U](f: Try[Nothing] => U)(implicit executor: ExecutionContext): Unit = ()
+ override def isCompleted: Boolean = false
+ override def value: Option[Try[Nothing]] = None
+ override def failed: Future[Throwable] = this
+ override def foreach[U](f: Nothing => U)(implicit executor: ExecutionContext): Unit = ()
+ override def transform[S](s: Nothing => S, f: Throwable => Throwable)(implicit executor: ExecutionContext): Future[S] = this
+ override def transform[S](f: Try[Nothing] => Try[S])(implicit executor: ExecutionContext): Future[S] = this
+ override def transformWith[S](f: Try[Nothing] => Future[S])(implicit executor: ExecutionContext): Future[S] = this
+ override def map[S](f: Nothing => S)(implicit executor: ExecutionContext): Future[S] = this
+ override def flatMap[S](f: Nothing => Future[S])(implicit executor: ExecutionContext): Future[S] = this
+ override def flatten[S](implicit ev: Nothing <:< Future[S]): Future[S] = this
+ override def filter(p: Nothing => Boolean)(implicit executor: ExecutionContext): Future[Nothing] = this
+ override def collect[S](pf: PartialFunction[Nothing, S])(implicit executor: ExecutionContext): Future[S] = this
+ override def recover[U >: Nothing](pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Future[U] = this
+ override def recoverWith[U >: Nothing](pf: PartialFunction[Throwable, Future[U]])(implicit executor: ExecutionContext): Future[U] = this
+ override def zip[U](that: Future[U]): Future[(Nothing, U)] = this
+ override def zipWith[U, R](that: Future[U])(f: (Nothing, U) => R)(implicit executor: ExecutionContext): Future[R] = this
+ override def fallbackTo[U >: Nothing](that: Future[U]): Future[U] = this
+ override def mapTo[S](implicit tag: ClassTag[S]): Future[S] = this
+ override def andThen[U](pf: PartialFunction[Try[Nothing], U])(implicit executor: ExecutionContext): Future[Nothing] = this
+
+ override def toString: String = "Future(<never>)"
+ }
+
+ /** A Future which is always completed with the Unit value.
+ */
+ val unit: Future[Unit] = successful(())
+
/** Creates an already completed Future with the specified exception.
*
- * @tparam T the type of the value in the future
- * @return the newly created `Future` object
+ * @tparam T the type of the value in the future
+ * @param exception the non-null instance of `Throwable`
+ * @return the newly created `Future` instance
*/
def failed[T](exception: Throwable): Future[T] = Promise.failed(exception).future
/** Creates an already completed Future with the specified result.
*
* @tparam T the type of the value in the future
- * @return the newly created `Future` object
+ * @param result the given successful value
+ * @return the newly created `Future` instance
*/
def successful[T](result: T): Future[T] = Promise.successful(result).future
/** Creates an already completed Future with the specified result or exception.
*
- * @tparam T the type of the value in the promise
- * @return the newly created `Future` object
+ * @tparam T the type of the value in the `Future`
+ * @param result the result of the returned `Future` instance
+ * @return the newly created `Future` instance
*/
def fromTry[T](result: Try[T]): Future[T] = Promise.fromTry(result).future
- /** Starts an asynchronous computation and returns a `Future` object with the result of that computation.
+ /** Starts an asynchronous computation and returns a `Future` instance with the result of that computation.
*
* The result becomes available once the asynchronous computation is completed.
*
- * @tparam T the type of the result
- * @param body the asynchronous computation
+ * @tparam T the type of the result
+ * @param body the asynchronous computation
* @param executor the execution context on which the future is run
- * @return the `Future` holding the result of the computation
+ * @return the `Future` holding the result of the computation
*/
- def apply[T](body: =>T)(implicit @deprecatedName('execctx) executor: ExecutionContext): Future[T] = impl.Future(body)
+ def apply[T](body: =>T)(implicit @deprecatedName('execctx) executor: ExecutionContext): Future[T] =
+ unit.map(_ => body)
- /** Simple version of `Future.traverse`. Transforms a `TraversableOnce[Future[A]]` into a `Future[TraversableOnce[A]]`.
- * Useful for reducing many `Future`s into a single `Future`.
+ /** Simple version of `Future.traverse`. Asynchronously and non-blockingly transforms a `TraversableOnce[Future[A]]`
+ * into a `Future[TraversableOnce[A]]`. Useful for reducing many `Future`s into a single `Future`.
+ *
+ * @tparam A the type of the value inside the Futures
+ * @tparam M the type of the `TraversableOnce` of Futures
+ * @param in the `TraversableOnce` of Futures which will be sequenced
+ * @return the `Future` of the `TraversableOnce` of results
*/
def sequence[A, M[X] <: TraversableOnce[X]](in: M[Future[A]])(implicit cbf: CanBuildFrom[M[Future[A]], A, M[A]], executor: ExecutionContext): Future[M[A]] = {
in.foldLeft(successful(cbf(in))) {
@@ -500,7 +613,12 @@ object Future {
} map (_.result())
}
- /** Returns a new `Future` to the result of the first future in the list that is completed.
+ /** Asynchronously and non-blockingly returns a new `Future` to the result of the first future
+ * in the list that is completed. This means no matter if it is completed as a success or as a failure.
+ *
+ * @tparam T the type of the value in the future
+ * @param futures the `TraversableOnce` of Futures in which to find the first completed
+ * @return the `Future` holding the result of the future that is first to be completed
*/
def firstCompletedOf[T](futures: TraversableOnce[Future[T]])(implicit executor: ExecutionContext): Future[T] = {
val p = Promise[T]()
@@ -509,8 +627,15 @@ object Future {
p.future
}
- /** Returns a `Future` that will hold the optional result of the first `Future` with a result that matches the predicate.
+ /** Asynchronously and non-blockingly returns a `Future` that will hold the optional result
+ * of the first `Future` with a result that matches the predicate.
+ *
+ * @tparam T the type of the value in the future
+ * @param futures the `TraversableOnce` of Futures to search
+ * @param p the predicate which indicates if it's a match
+ * @return the `Future` holding the optional result of the search
*/
+ @deprecated("Use the overloaded version of this method that takes a scala.collection.immutable.Iterable instead", "2.12")
def find[T](@deprecatedName('futurestravonce) futures: TraversableOnce[Future[T]])(@deprecatedName('predicate) p: T => Boolean)(implicit executor: ExecutionContext): Future[Option[T]] = {
val futuresBuffer = futures.toBuffer
if (futuresBuffer.isEmpty) successful[Option[T]](None)
@@ -534,40 +659,127 @@ object Future {
}
}
- /** A non-blocking fold over the specified futures, with the start value of the given zero.
+
+ /** Asynchronously and non-blockingly returns a `Future` that will hold the optional result
+ * of the first `Future` with a result that matches the predicate, failed `Future`s will be ignored.
+ *
+ * @tparam T the type of the value in the future
+ * @param futures the `scala.collection.immutable.Iterable` of Futures to search
+ * @param p the predicate which indicates if it's a match
+ * @return the `Future` holding the optional result of the search
+ */
+ def find[T](futures: scala.collection.immutable.Iterable[Future[T]])(p: T => Boolean)(implicit executor: ExecutionContext): Future[Option[T]] = {
+ def searchNext(i: Iterator[Future[T]]): Future[Option[T]] =
+ if (!i.hasNext) successful[Option[T]](None)
+ else {
+ i.next().transformWith {
+ case Success(r) if p(r) => successful(Some(r))
+ case other => searchNext(i)
+ }
+ }
+ searchNext(futures.iterator)
+ }
+
+ /** A non-blocking, asynchronous left fold over the specified futures,
+ * with the start value of the given zero.
+ * The fold is performed asynchronously in left-to-right order as the futures become completed.
+ * The result will be the first failure of any of the futures, or any failure in the actual fold,
+ * or the result of the fold.
+ *
+ * Example:
+ * {{{
+ * val futureSum = Future.foldLeft(futures)(0)(_ + _)
+ * }}}
+ *
+ * @tparam T the type of the value of the input Futures
+ * @tparam R the type of the value of the returned `Future`
+ * @param futures the `scala.collection.immutable.Iterable` of Futures to be folded
+ * @param zero the start value of the fold
+ * @param op the fold operation to be applied to the zero and futures
+ * @return the `Future` holding the result of the fold
+ */
+ def foldLeft[T, R](futures: scala.collection.immutable.Iterable[Future[T]])(zero: R)(op: (R, T) => R)(implicit executor: ExecutionContext): Future[R] =
+ foldNext(futures.iterator, zero, op)
+
+ private[this] def foldNext[T, R](i: Iterator[Future[T]], prevValue: R, op: (R, T) => R)(implicit executor: ExecutionContext): Future[R] =
+ if (!i.hasNext) successful(prevValue)
+ else i.next().flatMap { value => foldNext(i, op(prevValue, value), op) }
+
+ /** A non-blocking, asynchronous fold over the specified futures, with the start value of the given zero.
* The fold is performed on the thread where the last future is completed,
* the result will be the first failure of any of the futures, or any failure in the actual fold,
* or the result of the fold.
*
* Example:
* {{{
- * val result = Await.result(Future.fold(futures)(0)(_ + _), 5 seconds)
+ * val futureSum = Future.fold(futures)(0)(_ + _)
* }}}
+ *
+ * @tparam T the type of the value of the input Futures
+ * @tparam R the type of the value of the returned `Future`
+ * @param futures the `TraversableOnce` of Futures to be folded
+ * @param zero the start value of the fold
+ * @param op the fold operation to be applied to the zero and futures
+ * @return the `Future` holding the result of the fold
*/
+ @deprecated("Use Future.foldLeft instead", "2.12")
def fold[T, R](futures: TraversableOnce[Future[T]])(zero: R)(@deprecatedName('foldFun) op: (R, T) => R)(implicit executor: ExecutionContext): Future[R] = {
if (futures.isEmpty) successful(zero)
else sequence(futures).map(_.foldLeft(zero)(op))
}
- /** Initiates a fold over the supplied futures where the fold-zero is the result value of the `Future` that's completed first.
+ /** Initiates a non-blocking, asynchronous, fold over the supplied futures
+ * where the fold-zero is the result value of the `Future` that's completed first.
*
* Example:
* {{{
- * val result = Await.result(Future.reduce(futures)(_ + _), 5 seconds)
+ * val futureSum = Future.reduce(futures)(_ + _)
* }}}
+ * @tparam T the type of the value of the input Futures
+ * @tparam R the type of the value of the returned `Future`
+ * @param futures the `TraversableOnce` of Futures to be reduced
+ * @param op the reduce operation which is applied to the results of the futures
+ * @return the `Future` holding the result of the reduce
*/
+ @deprecated("Use Future.reduceLeft instead", "2.12")
def reduce[T, R >: T](futures: TraversableOnce[Future[T]])(op: (R, T) => R)(implicit executor: ExecutionContext): Future[R] = {
if (futures.isEmpty) failed(new NoSuchElementException("reduce attempted on empty collection"))
else sequence(futures).map(_ reduceLeft op)
}
- /** Transforms a `TraversableOnce[A]` into a `Future[TraversableOnce[B]]` using the provided function `A => Future[B]`.
+ /** Initiates a non-blocking, asynchronous, left reduction over the supplied futures
+ * where the zero is the result value of the first `Future`.
+ *
+ * Example:
+ * {{{
+ * val futureSum = Future.reduceLeft(futures)(_ + _)
+ * }}}
+ * @tparam T the type of the value of the input Futures
+ * @tparam R the type of the value of the returned `Future`
+ * @param futures the `scala.collection.immutable.Iterable` of Futures to be reduced
+ * @param op the reduce operation which is applied to the results of the futures
+ * @return the `Future` holding the result of the reduce
+ */
+ def reduceLeft[T, R >: T](futures: scala.collection.immutable.Iterable[Future[T]])(op: (R, T) => R)(implicit executor: ExecutionContext): Future[R] = {
+ val i = futures.iterator
+ if (!i.hasNext) failed(new NoSuchElementException("reduceLeft attempted on empty collection"))
+ else i.next() flatMap { v => foldNext(i, v, op) }
+ }
+
+ /** Asynchronously and non-blockingly transforms a `TraversableOnce[A]` into a `Future[TraversableOnce[B]]`
+ * using the provided function `A => Future[B]`.
* This is useful for performing a parallel map. For example, to apply a function to all items of a list
* in parallel:
*
* {{{
* val myFutureList = Future.traverse(myList)(x => Future(myFunc(x)))
* }}}
+ * @tparam A the type of the value inside the Futures in the `TraversableOnce`
+ * @tparam B the type of the value of the returned `Future`
+ * @tparam M the type of the `TraversableOnce` of Futures
+ * @param in the `TraversableOnce` of Futures which will be sequenced
+ * @param fn the function to apply to the `TraversableOnce` of Futures to produce the results
+ * @return the `Future` of the `TraversableOnce` of results
*/
def traverse[A, B, M[X] <: TraversableOnce[X]](in: M[A])(fn: A => Future[B])(implicit cbf: CanBuildFrom[M[A], B, M[B]], executor: ExecutionContext): Future[M[B]] =
in.foldLeft(successful(cbf(in))) { (fr, a) =>
@@ -575,6 +787,7 @@ object Future {
for (r <- fr; b <- fb) yield (r += b)
}.map(_.result())
+
// This is used to run callbacks which are internal
// to scala.concurrent; our own callbacks are only
// ever used to eventually run another callback,
diff --git a/src/library/scala/concurrent/Promise.scala b/src/library/scala/concurrent/Promise.scala
index 0f4e98db57..894b134e83 100644
--- a/src/library/scala/concurrent/Promise.scala
+++ b/src/library/scala/concurrent/Promise.scala
@@ -26,12 +26,6 @@ import scala.util.{ Try, Success, Failure }
* Note: Using this method may result in non-deterministic concurrent programs.
*/
trait Promise[T] {
-
- // used for internal callbacks defined in
- // the lexical scope of this trait;
- // _never_ for application callbacks.
- private implicit def internalExecutor: ExecutionContext = Future.InternalCallbackExecutor
-
/** Future containing the value of this promise.
*/
def future: Future[T]
@@ -73,7 +67,9 @@ trait Promise[T] {
* @return This promise
*/
final def tryCompleteWith(other: Future[T]): this.type = {
- other onComplete { this tryComplete _ }
+ if (other ne this.future) { // this tryCompleteWith this doesn't make much sense
+ other.onComplete(this tryComplete _)(Future.InternalCallbackExecutor)
+ }
this
}
@@ -139,5 +135,5 @@ object Promise {
* @tparam T the type of the value in the promise
* @return the newly created `Promise` object
*/
- def fromTry[T](result: Try[T]): Promise[T] = new impl.Promise.KeptPromise[T](result)
+ def fromTry[T](result: Try[T]): Promise[T] = impl.Promise.KeptPromise[T](result)
}
diff --git a/src/library/scala/concurrent/duration/Duration.scala b/src/library/scala/concurrent/duration/Duration.scala
index 182c2d172a..8b7d81d1c4 100644
--- a/src/library/scala/concurrent/duration/Duration.scala
+++ b/src/library/scala/concurrent/duration/Duration.scala
@@ -708,7 +708,7 @@ final class FiniteDuration(val length: Long, val unit: TimeUnit) extends Duratio
final def isFinite() = true
- final def toCoarsest: Duration = {
+ final override def toCoarsest: FiniteDuration = {
def loop(length: Long, unit: TimeUnit): FiniteDuration = {
def coarserOrThis(coarser: TimeUnit, divider: Int) =
if (length % divider == 0) loop(length / divider, coarser)
diff --git a/src/library/scala/concurrent/impl/AbstractPromise.java b/src/library/scala/concurrent/impl/AbstractPromise.java
deleted file mode 100644
index b8165b6cde..0000000000
--- a/src/library/scala/concurrent/impl/AbstractPromise.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala.concurrent.impl;
-
-
-import scala.concurrent.util.Unsafe;
-import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
-
-
-
-abstract class AbstractPromise {
- private volatile Object _ref;
-
- final static long _refoffset;
-
- static {
- try {
- _refoffset = Unsafe.instance.objectFieldOffset(AbstractPromise.class.getDeclaredField("_ref"));
- } catch (Throwable t) {
- throw new ExceptionInInitializerError(t);
- }
- }
-
- protected final boolean updateState(Object oldState, Object newState) {
- return Unsafe.instance.compareAndSwapObject(this, _refoffset, oldState, newState);
- }
-
- protected final Object getState() {
- return _ref;
- }
-
- protected final static AtomicReferenceFieldUpdater<AbstractPromise, Object> updater =
- AtomicReferenceFieldUpdater.newUpdater(AbstractPromise.class, Object.class, "_ref");
-} \ No newline at end of file
diff --git a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala
index 479720287c..0c7f98ce5a 100644
--- a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala
+++ b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala
@@ -11,52 +11,88 @@ package scala.concurrent.impl
import java.util.concurrent.{ LinkedBlockingQueue, Callable, Executor, ExecutorService, Executors, ThreadFactory, TimeUnit, ThreadPoolExecutor }
+import java.util.concurrent.atomic.AtomicInteger
import java.util.Collection
import scala.concurrent.forkjoin._
import scala.concurrent.{ BlockContext, ExecutionContext, Awaitable, CanAwait, ExecutionContextExecutor, ExecutionContextExecutorService }
import scala.util.control.NonFatal
+import scala.annotation.tailrec
+private[scala] class ExecutionContextImpl private[impl] (val executor: Executor, val reporter: Throwable => Unit) extends ExecutionContextExecutor {
+ require(executor ne null, "Executor must not be null")
+ override def execute(runnable: Runnable) = executor execute runnable
+ override def reportFailure(t: Throwable) = reporter(t)
+}
-private[scala] class ExecutionContextImpl private[impl] (es: Executor, reporter: Throwable => Unit) extends ExecutionContextExecutor {
- // Placed here since the creation of the executor needs to read this val
- private[this] val uncaughtExceptionHandler: Thread.UncaughtExceptionHandler = new Thread.UncaughtExceptionHandler {
- def uncaughtException(thread: Thread, cause: Throwable): Unit = reporter(cause)
- }
- val executor: Executor = es match {
- case null => createExecutorService
- case some => some
- }
+private[concurrent] object ExecutionContextImpl {
// Implement BlockContext on FJP threads
- class DefaultThreadFactory(daemonic: Boolean) extends ThreadFactory with ForkJoinPool.ForkJoinWorkerThreadFactory {
+ final class DefaultThreadFactory(
+ daemonic: Boolean,
+ maxThreads: Int,
+ prefix: String,
+ uncaught: Thread.UncaughtExceptionHandler) extends ThreadFactory with ForkJoinPool.ForkJoinWorkerThreadFactory {
+
+ require(prefix ne null, "DefaultThreadFactory.prefix must be non null")
+ require(maxThreads > 0, "DefaultThreadFactory.maxThreads must be greater than 0")
+
+ private final val currentNumberOfThreads = new AtomicInteger(0)
+
+ @tailrec private final def reserveThread(): Boolean = currentNumberOfThreads.get() match {
+ case `maxThreads` | Int.`MaxValue` => false
+ case other => currentNumberOfThreads.compareAndSet(other, other + 1) || reserveThread()
+ }
+
+ @tailrec private final def deregisterThread(): Boolean = currentNumberOfThreads.get() match {
+ case 0 => false
+ case other => currentNumberOfThreads.compareAndSet(other, other - 1) || deregisterThread()
+ }
+
def wire[T <: Thread](thread: T): T = {
thread.setDaemon(daemonic)
- thread.setUncaughtExceptionHandler(uncaughtExceptionHandler)
+ thread.setUncaughtExceptionHandler(uncaught)
+ thread.setName(prefix + "-" + thread.getId())
thread
}
- def newThread(runnable: Runnable): Thread = wire(new Thread(runnable))
-
- def newThread(fjp: ForkJoinPool): ForkJoinWorkerThread = wire(new ForkJoinWorkerThread(fjp) with BlockContext {
- override def blockOn[T](thunk: =>T)(implicit permission: CanAwait): T = {
- var result: T = null.asInstanceOf[T]
- ForkJoinPool.managedBlock(new ForkJoinPool.ManagedBlocker {
- @volatile var isdone = false
- override def block(): Boolean = {
- result = try thunk finally { isdone = true }
- true
+ // As per ThreadFactory contract newThread should return `null` if cannot create new thread.
+ def newThread(runnable: Runnable): Thread =
+ if (reserveThread())
+ wire(new Thread(new Runnable {
+ // We have to decrement the current thread count when the thread exits
+ override def run() = try runnable.run() finally deregisterThread()
+ })) else null
+
+ def newThread(fjp: ForkJoinPool): ForkJoinWorkerThread =
+ if (reserveThread()) {
+ wire(new ForkJoinWorkerThread(fjp) with BlockContext {
+ // We have to decrement the current thread count when the thread exits
+ final override def onTermination(exception: Throwable): Unit = deregisterThread()
+ final override def blockOn[T](thunk: =>T)(implicit permission: CanAwait): T = {
+ var result: T = null.asInstanceOf[T]
+ ForkJoinPool.managedBlock(new ForkJoinPool.ManagedBlocker {
+ @volatile var isdone = false
+ override def block(): Boolean = {
+ result = try {
+ // When we block, switch out the BlockContext temporarily so that nested blocking does not created N new Threads
+ BlockContext.withBlockContext(BlockContext.defaultBlockContext) { thunk }
+ } finally {
+ isdone = true
+ }
+
+ true
+ }
+ override def isReleasable = isdone
+ })
+ result
}
- override def isReleasable = isdone
})
- result
- }
- })
+ } else null
}
- def createExecutorService: ExecutorService = {
-
+ def createDefaultExecutorService(reporter: Throwable => Unit): ExecutorService = {
def getInt(name: String, default: String) = (try System.getProperty(name, default) catch {
case e: SecurityException => default
}) match {
@@ -65,20 +101,42 @@ private[scala] class ExecutionContextImpl private[impl] (es: Executor, reporter:
}
def range(floor: Int, desired: Int, ceiling: Int) = scala.math.min(scala.math.max(floor, desired), ceiling)
+ val numThreads = getInt("scala.concurrent.context.numThreads", "x1")
+ // The hard limit on the number of active threads that the thread factory will produce
+ // SI-8955 Deadlocks can happen if maxNoOfThreads is too low, although we're currently not sure
+ // about what the exact threshhold is. numThreads + 256 is conservatively high.
+ val maxNoOfThreads = getInt("scala.concurrent.context.maxThreads", "x1")
val desiredParallelism = range(
getInt("scala.concurrent.context.minThreads", "1"),
- getInt("scala.concurrent.context.numThreads", "x1"),
- getInt("scala.concurrent.context.maxThreads", "x1"))
+ numThreads,
+ maxNoOfThreads)
+
+ // The thread factory must provide additional threads to support managed blocking.
+ val maxExtraThreads = getInt("scala.concurrent.context.maxExtraThreads", "256")
+
+ val uncaughtExceptionHandler: Thread.UncaughtExceptionHandler = new Thread.UncaughtExceptionHandler {
+ override def uncaughtException(thread: Thread, cause: Throwable): Unit = reporter(cause)
+ }
- val threadFactory = new DefaultThreadFactory(daemonic = true)
+ val threadFactory = new ExecutionContextImpl.DefaultThreadFactory(daemonic = true,
+ maxThreads = maxNoOfThreads + maxExtraThreads,
+ prefix = "scala-execution-context-global",
+ uncaught = uncaughtExceptionHandler)
try {
- new ForkJoinPool(
- desiredParallelism,
- threadFactory,
- uncaughtExceptionHandler,
- true) // Async all the way baby
+ new ForkJoinPool(desiredParallelism, threadFactory, uncaughtExceptionHandler, true) {
+ override def execute(runnable: Runnable): Unit = {
+ val fjt: ForkJoinTask[_] = runnable match {
+ case t: ForkJoinTask[_] => t
+ case r => new ExecutionContextImpl.AdaptedForkJoinTask(r)
+ }
+ Thread.currentThread match {
+ case fjw: ForkJoinWorkerThread if fjw.getPool eq this => fjt.fork()
+ case _ => super.execute(fjt)
+ }
+ }
+ }
} catch {
case NonFatal(t) =>
System.err.println("Failed to create ForkJoinPool for the default ExecutionContext, falling back to ThreadPoolExecutor")
@@ -96,56 +154,42 @@ private[scala] class ExecutionContextImpl private[impl] (es: Executor, reporter:
}
}
- def execute(runnable: Runnable): Unit = executor match {
- case fj: ForkJoinPool =>
- val fjt: ForkJoinTask[_] = runnable match {
- case t: ForkJoinTask[_] => t
- case r => new ExecutionContextImpl.AdaptedForkJoinTask(r)
- }
- Thread.currentThread match {
- case fjw: ForkJoinWorkerThread if fjw.getPool eq fj => fjt.fork()
- case _ => fj execute fjt
- }
- case generic => generic execute runnable
- }
-
- def reportFailure(t: Throwable) = reporter(t)
-}
-
-
-private[concurrent] object ExecutionContextImpl {
-
final class AdaptedForkJoinTask(runnable: Runnable) extends ForkJoinTask[Unit] {
- final override def setRawResult(u: Unit): Unit = ()
- final override def getRawResult(): Unit = ()
- final override def exec(): Boolean = try { runnable.run(); true } catch {
- case anything: Throwable ⇒
- val t = Thread.currentThread
- t.getUncaughtExceptionHandler match {
- case null ⇒
- case some ⇒ some.uncaughtException(t, anything)
- }
- throw anything
- }
+ final override def setRawResult(u: Unit): Unit = ()
+ final override def getRawResult(): Unit = ()
+ final override def exec(): Boolean = try { runnable.run(); true } catch {
+ case anything: Throwable =>
+ val t = Thread.currentThread
+ t.getUncaughtExceptionHandler match {
+ case null =>
+ case some => some.uncaughtException(t, anything)
}
+ throw anything
+ }
+ }
- def fromExecutor(e: Executor, reporter: Throwable => Unit = ExecutionContext.defaultReporter): ExecutionContextImpl = new ExecutionContextImpl(e, reporter)
- def fromExecutorService(es: ExecutorService, reporter: Throwable => Unit = ExecutionContext.defaultReporter): ExecutionContextImpl with ExecutionContextExecutorService =
- new ExecutionContextImpl(es, reporter) with ExecutionContextExecutorService {
- final def asExecutorService: ExecutorService = executor.asInstanceOf[ExecutorService]
- override def execute(command: Runnable) = executor.execute(command)
- override def shutdown() { asExecutorService.shutdown() }
- override def shutdownNow() = asExecutorService.shutdownNow()
- override def isShutdown = asExecutorService.isShutdown
- override def isTerminated = asExecutorService.isTerminated
- override def awaitTermination(l: Long, timeUnit: TimeUnit) = asExecutorService.awaitTermination(l, timeUnit)
- override def submit[T](callable: Callable[T]) = asExecutorService.submit(callable)
- override def submit[T](runnable: Runnable, t: T) = asExecutorService.submit(runnable, t)
- override def submit(runnable: Runnable) = asExecutorService.submit(runnable)
- override def invokeAll[T](callables: Collection[_ <: Callable[T]]) = asExecutorService.invokeAll(callables)
- override def invokeAll[T](callables: Collection[_ <: Callable[T]], l: Long, timeUnit: TimeUnit) = asExecutorService.invokeAll(callables, l, timeUnit)
- override def invokeAny[T](callables: Collection[_ <: Callable[T]]) = asExecutorService.invokeAny(callables)
- override def invokeAny[T](callables: Collection[_ <: Callable[T]], l: Long, timeUnit: TimeUnit) = asExecutorService.invokeAny(callables, l, timeUnit)
+ def fromExecutor(e: Executor, reporter: Throwable => Unit = ExecutionContext.defaultReporter): ExecutionContextImpl =
+ new ExecutionContextImpl(Option(e).getOrElse(createDefaultExecutorService(reporter)), reporter)
+
+ def fromExecutorService(es: ExecutorService, reporter: Throwable => Unit = ExecutionContext.defaultReporter):
+ ExecutionContextImpl with ExecutionContextExecutorService = {
+ new ExecutionContextImpl(Option(es).getOrElse(createDefaultExecutorService(reporter)), reporter)
+ with ExecutionContextExecutorService {
+ final def asExecutorService: ExecutorService = executor.asInstanceOf[ExecutorService]
+ override def execute(command: Runnable) = executor.execute(command)
+ override def shutdown() { asExecutorService.shutdown() }
+ override def shutdownNow() = asExecutorService.shutdownNow()
+ override def isShutdown = asExecutorService.isShutdown
+ override def isTerminated = asExecutorService.isTerminated
+ override def awaitTermination(l: Long, timeUnit: TimeUnit) = asExecutorService.awaitTermination(l, timeUnit)
+ override def submit[T](callable: Callable[T]) = asExecutorService.submit(callable)
+ override def submit[T](runnable: Runnable, t: T) = asExecutorService.submit(runnable, t)
+ override def submit(runnable: Runnable) = asExecutorService.submit(runnable)
+ override def invokeAll[T](callables: Collection[_ <: Callable[T]]) = asExecutorService.invokeAll(callables)
+ override def invokeAll[T](callables: Collection[_ <: Callable[T]], l: Long, timeUnit: TimeUnit) = asExecutorService.invokeAll(callables, l, timeUnit)
+ override def invokeAny[T](callables: Collection[_ <: Callable[T]]) = asExecutorService.invokeAny(callables)
+ override def invokeAny[T](callables: Collection[_ <: Callable[T]], l: Long, timeUnit: TimeUnit) = asExecutorService.invokeAny(callables, l, timeUnit)
+ }
}
}
diff --git a/src/library/scala/concurrent/impl/Future.scala b/src/library/scala/concurrent/impl/Future.scala
deleted file mode 100644
index 042d32c234..0000000000
--- a/src/library/scala/concurrent/impl/Future.scala
+++ /dev/null
@@ -1,34 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala.concurrent.impl
-
-
-
-import scala.concurrent.ExecutionContext
-import scala.util.control.NonFatal
-import scala.util.{ Success, Failure }
-
-
-private[concurrent] object Future {
- class PromiseCompletingRunnable[T](body: => T) extends Runnable {
- val promise = new Promise.DefaultPromise[T]()
-
- override def run() = {
- promise complete {
- try Success(body) catch { case NonFatal(e) => Failure(e) }
- }
- }
- }
-
- def apply[T](body: =>T)(implicit executor: ExecutionContext): scala.concurrent.Future[T] = {
- val runnable = new PromiseCompletingRunnable(body)
- executor.prepare.execute(runnable)
- runnable.promise.future
- }
-}
diff --git a/src/library/scala/concurrent/impl/Promise.scala b/src/library/scala/concurrent/impl/Promise.scala
index b15601058e..078ad45be9 100644
--- a/src/library/scala/concurrent/impl/Promise.scala
+++ b/src/library/scala/concurrent/impl/Promise.scala
@@ -16,14 +16,42 @@ import scala.util.control.NonFatal
import scala.util.{ Try, Success, Failure }
import java.io.ObjectInputStream
import java.util.concurrent.locks.AbstractQueuedSynchronizer
+import java.util.concurrent.atomic.AtomicReference
private[concurrent] trait Promise[T] extends scala.concurrent.Promise[T] with scala.concurrent.Future[T] {
def future: this.type = this
+
+ import scala.concurrent.Future
+ import scala.concurrent.impl.Promise.DefaultPromise
+
+ override def transform[S](f: Try[T] => Try[S])(implicit executor: ExecutionContext): Future[S] = {
+ val p = new DefaultPromise[S]()
+ onComplete { result => p.complete(try f(result) catch { case NonFatal(t) => Failure(t) }) }
+ p.future
+ }
+
+ // If possible, link DefaultPromises to avoid space leaks
+ override def transformWith[S](f: Try[T] => Future[S])(implicit executor: ExecutionContext): Future[S] = {
+ val p = new DefaultPromise[S]()
+ onComplete {
+ v => try f(v) match {
+ case fut if fut eq this => p complete v.asInstanceOf[Try[S]]
+ case dp: DefaultPromise[_] => dp.asInstanceOf[DefaultPromise[S]].linkRootOf(p)
+ case fut => p completeWith fut
+ } catch { case NonFatal(t) => p failure t }
+ }
+ p.future
+ }
+
+ override def toString: String = value match {
+ case Some(result) => "Future("+result+")"
+ case None => "Future(<not completed>)"
+ }
}
/* Precondition: `executor` is prepared, i.e., `executor` has been returned from invocation of `prepare` on some other `ExecutionContext`.
*/
-private class CallbackRunnable[T](val executor: ExecutionContext, val onComplete: Try[T] => Any) extends Runnable with OnCompleteRunnable {
+private final class CallbackRunnable[T](val executor: ExecutionContext, val onComplete: Try[T] => Any) extends Runnable with OnCompleteRunnable {
// must be filled in before running it
var value: Try[T] = null
@@ -89,7 +117,7 @@ private[concurrent] object Promise {
* incomplete, or as complete with the same result value.
*
* A DefaultPromise stores its state entirely in the AnyRef cell exposed by
- * AbstractPromise. The type of object stored in the cell fully describes the
+ * AtomicReference. The type of object stored in the cell fully describes the
* current state of the promise.
*
* 1. List[CallbackRunnable] - The promise is incomplete and has zero or more callbacks
@@ -150,8 +178,7 @@ private[concurrent] object Promise {
* DefaultPromises, and `linkedRootOf` is currently only designed to be called
* by Future.flatMap.
*/
- class DefaultPromise[T] extends AbstractPromise with Promise[T] { self =>
- updateState(null, Nil) // The promise is incomplete and has no callbacks
+ final class DefaultPromise[T] extends AtomicReference[AnyRef](Nil) with Promise[T] {
/** Get the root promise for this promise, compressing the link chain to that
* promise if necessary.
@@ -167,14 +194,23 @@ private[concurrent] object Promise {
* be garbage collected. Also, subsequent calls to this method should be
* faster as the link chain will be shorter.
*/
- @tailrec
- private def compressedRoot(): DefaultPromise[T] = {
- getState match {
- case linked: DefaultPromise[_] =>
- val target = linked.asInstanceOf[DefaultPromise[T]].root
- if (linked eq target) target else if (updateState(linked, target)) target else compressedRoot()
+ private def compressedRoot(): DefaultPromise[T] =
+ get() match {
+ case linked: DefaultPromise[_] => compressedRoot(linked)
case _ => this
}
+
+ @tailrec
+ private[this] final def compressedRoot(linked: DefaultPromise[_]): DefaultPromise[T] = {
+ val target = linked.asInstanceOf[DefaultPromise[T]].root
+ if (linked eq target) target
+ else if (compareAndSet(linked, target)) target
+ else {
+ get() match {
+ case newLinked: DefaultPromise[_] => compressedRoot(newLinked)
+ case _ => this
+ }
+ }
}
/** Get the promise at the root of the chain of linked promises. Used by `compressedRoot()`.
@@ -182,18 +218,16 @@ private[concurrent] object Promise {
* to compress the link chain whenever possible.
*/
@tailrec
- private def root: DefaultPromise[T] = {
- getState match {
+ private def root: DefaultPromise[T] =
+ get() match {
case linked: DefaultPromise[_] => linked.asInstanceOf[DefaultPromise[T]].root
case _ => this
}
- }
/** Try waiting for this promise to be completed.
*/
protected final def tryAwait(atMost: Duration): Boolean = if (!isCompleted) {
import Duration.Undefined
- import scala.concurrent.Future.InternalCallbackExecutor
atMost match {
case e if e eq Undefined => throw new IllegalArgumentException("cannot wait for Undefined period")
case Duration.Inf =>
@@ -225,18 +259,18 @@ private[concurrent] object Promise {
def value: Option[Try[T]] = value0
@tailrec
- private def value0: Option[Try[T]] = getState match {
+ private def value0: Option[Try[T]] = get() match {
case c: Try[_] => Some(c.asInstanceOf[Try[T]])
- case _: DefaultPromise[_] => compressedRoot().value0
+ case dp: DefaultPromise[_] => compressedRoot(dp).value0
case _ => None
}
override def isCompleted: Boolean = isCompleted0
@tailrec
- private def isCompleted0: Boolean = getState match {
+ private def isCompleted0: Boolean = get() match {
case _: Try[_] => true
- case _: DefaultPromise[_] => compressedRoot().isCompleted0
+ case dp: DefaultPromise[_] => compressedRoot(dp).isCompleted0
case _ => false
}
@@ -254,21 +288,17 @@ private[concurrent] object Promise {
*/
@tailrec
private def tryCompleteAndGetListeners(v: Try[T]): List[CallbackRunnable[T]] = {
- getState match {
+ get() match {
case raw: List[_] =>
val cur = raw.asInstanceOf[List[CallbackRunnable[T]]]
- if (updateState(cur, v)) cur else tryCompleteAndGetListeners(v)
- case _: DefaultPromise[_] =>
- compressedRoot().tryCompleteAndGetListeners(v)
+ if (compareAndSet(cur, v)) cur else tryCompleteAndGetListeners(v)
+ case dp: DefaultPromise[_] => compressedRoot(dp).tryCompleteAndGetListeners(v)
case _ => null
}
}
- def onComplete[U](func: Try[T] => U)(implicit executor: ExecutionContext): Unit = {
- val preparedEC = executor.prepare()
- val runnable = new CallbackRunnable[T](preparedEC, func)
- dispatchOrAddCallback(runnable)
- }
+ def onComplete[U](func: Try[T] => U)(implicit executor: ExecutionContext): Unit =
+ dispatchOrAddCallback(new CallbackRunnable[T](executor.prepare(), func))
/** Tries to add the callback, if already completed, it dispatches the callback to be executed.
* Used by `onComplete()` to add callbacks to a promise and by `link()` to transfer callbacks
@@ -276,15 +306,16 @@ private[concurrent] object Promise {
*/
@tailrec
private def dispatchOrAddCallback(runnable: CallbackRunnable[T]): Unit = {
- getState match {
+ get() match {
case r: Try[_] => runnable.executeWithValue(r.asInstanceOf[Try[T]])
- case _: DefaultPromise[_] => compressedRoot().dispatchOrAddCallback(runnable)
- case listeners: List[_] => if (updateState(listeners, runnable :: listeners)) () else dispatchOrAddCallback(runnable)
+ case dp: DefaultPromise[_] => compressedRoot(dp).dispatchOrAddCallback(runnable)
+ case listeners: List[_] => if (compareAndSet(listeners, runnable :: listeners)) ()
+ else dispatchOrAddCallback(runnable)
}
}
/** Link this promise to the root of another promise using `link()`. Should only be
- * be called by Future.flatMap.
+ * be called by transformWith.
*/
protected[concurrent] final def linkRootOf(target: DefaultPromise[T]): Unit = link(target.compressedRoot())
@@ -299,18 +330,17 @@ private[concurrent] object Promise {
*/
@tailrec
private def link(target: DefaultPromise[T]): Unit = if (this ne target) {
- getState match {
+ get() match {
case r: Try[_] =>
- if (!target.tryComplete(r.asInstanceOf[Try[T]])) {
- // Currently linking is done from Future.flatMap, which should ensure only
- // one promise can be completed. Therefore this situation is unexpected.
+ if (!target.tryComplete(r.asInstanceOf[Try[T]]))
throw new IllegalStateException("Cannot link completed promises together")
- }
- case _: DefaultPromise[_] =>
- compressedRoot().link(target)
- case listeners: List[_] => if (updateState(listeners, target)) {
- if (!listeners.isEmpty) listeners.asInstanceOf[List[CallbackRunnable[T]]].foreach(target.dispatchOrAddCallback(_))
- } else link(target)
+ case dp: DefaultPromise[_] =>
+ compressedRoot(dp).link(target)
+ case listeners: List[_] if compareAndSet(listeners, target) =>
+ if (listeners.nonEmpty)
+ listeners.asInstanceOf[List[CallbackRunnable[T]]].foreach(target.dispatchOrAddCallback(_))
+ case _ =>
+ link(target)
}
}
}
@@ -319,23 +349,58 @@ private[concurrent] object Promise {
*
* Useful in Future-composition when a value to contribute is already available.
*/
- final class KeptPromise[T](suppliedValue: Try[T]) extends Promise[T] {
+ object KeptPromise {
+ import scala.concurrent.Future
+ import scala.reflect.ClassTag
+
+ private[this] sealed trait Kept[T] extends Promise[T] {
+ def result: Try[T]
+
+ override def value: Option[Try[T]] = Some(result)
- val value = Some(resolveTry(suppliedValue))
+ override def isCompleted: Boolean = true
- override def isCompleted: Boolean = true
+ override def tryComplete(value: Try[T]): Boolean = false
- def tryComplete(value: Try[T]): Boolean = false
+ override def onComplete[U](func: Try[T] => U)(implicit executor: ExecutionContext): Unit =
+ (new CallbackRunnable(executor.prepare(), func)).executeWithValue(result)
- def onComplete[U](func: Try[T] => U)(implicit executor: ExecutionContext): Unit = {
- val completedAs = value.get
- val preparedEC = executor.prepare()
- (new CallbackRunnable(preparedEC, func)).executeWithValue(completedAs)
+ override def ready(atMost: Duration)(implicit permit: CanAwait): this.type = this
+
+ override def result(atMost: Duration)(implicit permit: CanAwait): T = result.get
}
- def ready(atMost: Duration)(implicit permit: CanAwait): this.type = this
+ private[this] final class Successful[T](val result: Success[T]) extends Kept[T] {
+ override def onFailure[U](pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Unit = ()
+ override def failed: Future[Throwable] = KeptPromise(Failure(new NoSuchElementException("Future.failed not completed with a throwable."))).future
+ override def recover[U >: T](pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Future[U] = this
+ override def recoverWith[U >: T](pf: PartialFunction[Throwable, Future[U]])(implicit executor: ExecutionContext): Future[U] = this
+ override def fallbackTo[U >: T](that: Future[U]): Future[U] = this
+ }
- def result(atMost: Duration)(implicit permit: CanAwait): T = value.get.get
+ private[this] final class Failed[T](val result: Failure[T]) extends Kept[T] {
+ private[this] final def thisAs[S]: Future[S] = future.asInstanceOf[Future[S]]
+
+ override def onSuccess[U](pf: PartialFunction[T, U])(implicit executor: ExecutionContext): Unit = ()
+ override def failed: Future[Throwable] = thisAs[Throwable]
+ override def foreach[U](f: T => U)(implicit executor: ExecutionContext): Unit = ()
+ override def map[S](f: T => S)(implicit executor: ExecutionContext): Future[S] = thisAs[S]
+ override def flatMap[S](f: T => Future[S])(implicit executor: ExecutionContext): Future[S] = thisAs[S]
+ override def flatten[S](implicit ev: T <:< Future[S]): Future[S] = thisAs[S]
+ override def filter(p: T => Boolean)(implicit executor: ExecutionContext): Future[T] = this
+ override def collect[S](pf: PartialFunction[T, S])(implicit executor: ExecutionContext): Future[S] = thisAs[S]
+ override def zip[U](that: Future[U]): Future[(T, U)] = thisAs[(T,U)]
+ override def zipWith[U, R](that: Future[U])(f: (T, U) => R)(implicit executor: ExecutionContext): Future[R] = thisAs[R]
+ override def fallbackTo[U >: T](that: Future[U]): Future[U] =
+ if (this eq that) this else that.recoverWith({ case _ => this })(InternalCallbackExecutor)
+ override def mapTo[S](implicit tag: ClassTag[S]): Future[S] = thisAs[S]
+ }
+
+ def apply[T](result: Try[T]): scala.concurrent.Promise[T] =
+ resolveTry(result) match {
+ case s @ Success(_) => new Successful(s)
+ case f @ Failure(_) => new Failed(f)
+ }
}
}
diff --git a/src/library/scala/deprecatedName.scala b/src/library/scala/deprecatedName.scala
index 07c5c8925c..a0d3aa829b 100644
--- a/src/library/scala/deprecatedName.scala
+++ b/src/library/scala/deprecatedName.scala
@@ -29,4 +29,6 @@ import scala.annotation.meta._
* @since 2.8.1
*/
@param
-class deprecatedName(name: Symbol) extends scala.annotation.StaticAnnotation
+class deprecatedName(name: Symbol) extends scala.annotation.StaticAnnotation {
+ def this() = this(Symbol("<none>"))
+}
diff --git a/src/library/scala/io/Source.scala b/src/library/scala/io/Source.scala
index 9f0b56b4fe..e38c197196 100644
--- a/src/library/scala/io/Source.scala
+++ b/src/library/scala/io/Source.scala
@@ -10,7 +10,7 @@ package scala
package io
import scala.collection.AbstractIterator
-import java.io.{ FileInputStream, InputStream, PrintStream, File => JFile }
+import java.io.{ FileInputStream, InputStream, PrintStream, File => JFile, Closeable }
import java.net.{ URI, URL }
/** This object provides convenience methods to create an iterable
@@ -187,7 +187,7 @@ object Source {
* @author Burak Emir
* @version 1.0
*/
-abstract class Source extends Iterator[Char] {
+abstract class Source extends Iterator[Char] with Closeable {
/** the actual iterator */
protected val iter: Iterator[Char]
diff --git a/src/library/scala/math/package.scala b/src/library/scala/math/package.scala
index 58ece8a05b..b6593d6661 100644
--- a/src/library/scala/math/package.scala
+++ b/src/library/scala/math/package.scala
@@ -26,7 +26,7 @@ package object math {
/** Returns a `double` value with a positive sign, greater than or equal
* to `0.0` and less than `1.0`.
*/
- def random: Double = java.lang.Math.random()
+ def random(): Double = java.lang.Math.random()
def sin(x: Double): Double = java.lang.Math.sin(x)
def cos(x: Double): Double = java.lang.Math.cos(x)
diff --git a/src/library/scala/runtime/BoxesRunTime.java b/src/library/scala/runtime/BoxesRunTime.java
index 9cb1dee41c..96e0f23f3d 100644
--- a/src/library/scala/runtime/BoxesRunTime.java
+++ b/src/library/scala/runtime/BoxesRunTime.java
@@ -179,7 +179,7 @@ public final class BoxesRunTime
return xc.equals(y);
}
- private static boolean equalsNumChar(java.lang.Number xn, java.lang.Character yc) {
+ public static boolean equalsNumChar(java.lang.Number xn, java.lang.Character yc) {
if (yc == null)
return xn == null;
diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala
index 18fcbf8276..a0d89fc0e1 100644
--- a/src/library/scala/runtime/ScalaRunTime.scala
+++ b/src/library/scala/runtime/ScalaRunTime.scala
@@ -13,6 +13,7 @@ import scala.collection.{ Seq, IndexedSeq, TraversableView, AbstractIterator }
import scala.collection.mutable.WrappedArray
import scala.collection.immutable.{ StringLike, NumericRange, List, Stream, Nil, :: }
import scala.collection.generic.{ Sorted, IsTraversableLike }
+import scala.collection.parallel.ParIterable
import scala.reflect.{ ClassTag, classTag }
import scala.util.control.ControlThrowable
import java.lang.{ Class => jClass }
@@ -326,6 +327,7 @@ object ScalaRunTime {
case x: AnyRef if isArray(x) => arrayToString(x)
case x: scala.collection.Map[_, _] => x.iterator take maxElements map mapInner mkString (x.stringPrefix + "(", ", ", ")")
case x: Iterable[_] => x.iterator take maxElements map inner mkString (x.stringPrefix + "(", ", ", ")")
+ case x: ParIterable[_] => x.iterator take maxElements map inner mkString (x.stringPrefix + "(", ", ", ")")
case x: Traversable[_] => x take maxElements map inner mkString (x.stringPrefix + "(", ", ", ")")
case x: Product1[_] if isTuple(x) => "(" + inner(x._1) + ",)" // that special trailing comma
case x: Product if isTuple(x) => x.productIterator map inner mkString ("(", ",", ")")
diff --git a/src/library/scala/sys/SystemProperties.scala b/src/library/scala/sys/SystemProperties.scala
index d2ebf8c044..6f8b13a89b 100644
--- a/src/library/scala/sys/SystemProperties.scala
+++ b/src/library/scala/sys/SystemProperties.scala
@@ -35,8 +35,15 @@ extends mutable.AbstractMap[String, String]
override def empty = new SystemProperties
override def default(key: String): String = null
- def iterator: Iterator[(String, String)] =
- wrapAccess(System.getProperties().asScala.iterator) getOrElse Iterator.empty
+ def iterator: Iterator[(String, String)] = wrapAccess {
+ val ps = System.getProperties()
+ names map (k => (k, ps getProperty k)) filter (_._2 ne null)
+ } getOrElse Iterator.empty
+
+ def names: Iterator[String] = wrapAccess (
+ System.getProperties().stringPropertyNames().asScala.iterator
+ ) getOrElse Iterator.empty
+
def get(key: String) =
wrapAccess(Option(System.getProperty(key))) flatMap (x => x)
override def contains(key: String) =
diff --git a/src/library/scala/sys/process/BasicIO.scala b/src/library/scala/sys/process/BasicIO.scala
index 066b2f5373..640f7e68c2 100644
--- a/src/library/scala/sys/process/BasicIO.scala
+++ b/src/library/scala/sys/process/BasicIO.scala
@@ -221,7 +221,7 @@ object BasicIO {
*/
def transferFully(in: InputStream, out: OutputStream): Unit =
try transferFullyImpl(in, out)
- catch onInterrupt(())
+ catch onIOInterrupt(())
private[this] def appendLine(buffer: Appendable): String => Unit = line => {
buffer append line
diff --git a/src/library/scala/sys/process/ProcessImpl.scala b/src/library/scala/sys/process/ProcessImpl.scala
index 2b7fcdeb73..d15f1a2b3d 100644
--- a/src/library/scala/sys/process/ProcessImpl.scala
+++ b/src/library/scala/sys/process/ProcessImpl.scala
@@ -109,45 +109,46 @@ private[process] trait ProcessImpl {
}
private[process] class PipedProcesses(a: ProcessBuilder, b: ProcessBuilder, defaultIO: ProcessIO, toError: Boolean) extends CompoundProcess {
- protected[this] override def runAndExitValue() = {
- val currentSource = new SyncVar[Option[InputStream]]
- val pipeOut = new PipedOutputStream
- val source = new PipeSource(currentSource, pipeOut, a.toString)
+ protected[this] override def runAndExitValue() = runAndExitValue(new PipeSource(a.toString), new PipeSink(b.toString))
+ protected[this] def runAndExitValue(source: PipeSource, sink: PipeSink): Option[Int] = {
+ source connectOut sink
source.start()
-
- val pipeIn = new PipedInputStream(pipeOut)
- val currentSink = new SyncVar[Option[OutputStream]]
- val sink = new PipeSink(pipeIn, currentSink, b.toString)
sink.start()
- def handleOutOrError(fromOutput: InputStream) = currentSource put Some(fromOutput)
+ /** Release PipeSource, PipeSink and Process in the correct order.
+ * If once connect Process with Source or Sink, then the order of releasing them
+ * must be Source -> Sink -> Process, otherwise IOException will be thrown. */
+ def releaseResources(so: PipeSource, sk: PipeSink, p: Process *) = {
+ so.release()
+ sk.release()
+ p foreach( _.destroy() )
+ }
val firstIO =
- if (toError)
- defaultIO.withError(handleOutOrError)
- else
- defaultIO.withOutput(handleOutOrError)
- val secondIO = defaultIO.withInput(toInput => currentSink put Some(toInput))
-
- val second = b.run(secondIO)
- val first = a.run(firstIO)
- try {
- runInterruptible {
- val exit1 = first.exitValue()
- currentSource put None
- currentSink put None
- val exit2 = second.exitValue()
- // Since file redirection (e.g. #>) is implemented as a piped process,
- // we ignore its exit value so cmd #> file doesn't always return 0.
- if (b.hasExitValue) exit2 else exit1
- } {
- first.destroy()
- second.destroy()
+ if (toError) defaultIO.withError(source.connectIn)
+ else defaultIO.withOutput(source.connectIn)
+ val secondIO = defaultIO.withInput(sink.connectOut)
+
+ val second =
+ try b.run(secondIO)
+ catch onError { err =>
+ releaseResources(source, sink)
+ throw err
}
- }
- finally {
- BasicIO close pipeIn
- BasicIO close pipeOut
+ val first =
+ try a.run(firstIO)
+ catch onError { err =>
+ releaseResources(source, sink, second)
+ throw err
+ }
+ runInterruptible {
+ val exit1 = first.exitValue()
+ val exit2 = second.exitValue()
+ // Since file redirection (e.g. #>) is implemented as a piped process,
+ // we ignore its exit value so cmd #> file doesn't always return 0.
+ if (b.hasExitValue) exit2 else exit1
+ } {
+ releaseResources(source, sink, first, second)
}
}
}
@@ -168,37 +169,46 @@ private[process] trait ProcessImpl {
}
}
- private[process] class PipeSource(
- currentSource: SyncVar[Option[InputStream]],
- pipe: PipedOutputStream,
- label: => String
- ) extends PipeThread(false, () => label) {
-
- final override def run(): Unit = currentSource.get match {
- case Some(source) =>
- try runloop(source, pipe)
- finally currentSource.unset()
-
- run()
- case None =>
- currentSource.unset()
- BasicIO close pipe
+ private[process] class PipeSource(label: => String) extends PipeThread(false, () => label) {
+ protected[this] val pipe = new PipedOutputStream
+ protected[this] val source = new LinkedBlockingQueue[Option[InputStream]]
+ override def run(): Unit = {
+ try {
+ source.take match {
+ case Some(in) => runloop(in, pipe)
+ case None =>
+ }
+ }
+ catch onInterrupt(())
+ finally BasicIO close pipe
+ }
+ def connectIn(in: InputStream): Unit = source add Some(in)
+ def connectOut(sink: PipeSink): Unit = sink connectIn pipe
+ def release(): Unit = {
+ interrupt()
+ source add None
+ join()
}
}
- private[process] class PipeSink(
- pipe: PipedInputStream,
- currentSink: SyncVar[Option[OutputStream]],
- label: => String
- ) extends PipeThread(true, () => label) {
-
- final override def run(): Unit = currentSink.get match {
- case Some(sink) =>
- try runloop(pipe, sink)
- finally currentSink.unset()
-
- run()
- case None =>
- currentSink.unset()
+ private[process] class PipeSink(label: => String) extends PipeThread(true, () => label) {
+ protected[this] val pipe = new PipedInputStream
+ protected[this] val sink = new LinkedBlockingQueue[Option[OutputStream]]
+ override def run(): Unit = {
+ try {
+ sink.take match {
+ case Some(out) => runloop(pipe, out)
+ case None =>
+ }
+ }
+ catch onInterrupt(())
+ finally BasicIO close pipe
+ }
+ def connectOut(out: OutputStream): Unit = sink add Some(out)
+ def connectIn(pipeOut: PipedOutputStream): Unit = pipe connect pipeOut
+ def release(): Unit = {
+ interrupt()
+ sink add None
+ join()
}
}
diff --git a/src/library/scala/sys/process/package.scala b/src/library/scala/sys/process/package.scala
index b1976ad4b6..5ec2e73cb9 100644
--- a/src/library/scala/sys/process/package.scala
+++ b/src/library/scala/sys/process/package.scala
@@ -224,16 +224,26 @@ package scala.sys {
final val processDebug = props contains "scala.process.debug"
dbg("Initializing process package.")
- type =?>[-A, +B] = PartialFunction[A, B]
- type Closeable = java.io.Closeable
- type File = java.io.File
- type IOException = java.io.IOException
- type InputStream = java.io.InputStream
- type JProcess = java.lang.Process
- type JProcessBuilder = java.lang.ProcessBuilder
- type OutputStream = java.io.OutputStream
- type SyncVar[T] = scala.concurrent.SyncVar[T]
- type URL = java.net.URL
+ type =?>[-A, +B] = PartialFunction[A, B]
+ type Closeable = java.io.Closeable
+ type File = java.io.File
+ type IOException = java.io.IOException
+ type InterruptedIOException = java.io.InterruptedIOException
+ type InputStream = java.io.InputStream
+ type JProcess = java.lang.Process
+ type JProcessBuilder = java.lang.ProcessBuilder
+ type LinkedBlockingQueue[T] = java.util.concurrent.LinkedBlockingQueue[T]
+ type OutputStream = java.io.OutputStream
+ type SyncVar[T] = scala.concurrent.SyncVar[T]
+ type URL = java.net.URL
+
+ def onError[T](handler: Throwable => T): Throwable =?> T = {
+ case e @ _ => handler(e)
+ }
+
+ def onIOInterrupt[T](handler: => T): Throwable =?> T = {
+ case _: InterruptedIOException => handler
+ }
def onInterrupt[T](handler: => T): Throwable =?> T = {
case _: InterruptedException => handler
diff --git a/src/library/scala/util/Either.scala b/src/library/scala/util/Either.scala
index e196d403c2..6ea9da64f2 100644
--- a/src/library/scala/util/Either.scala
+++ b/src/library/scala/util/Either.scala
@@ -68,7 +68,7 @@ import scala.language.implicitConversions
* @version 1.0, 11/10/2008
* @since 2.7
*/
-sealed abstract class Either[+A, +B] {
+sealed abstract class Either[+A, +B] extends Product with Serializable {
/**
* Projects this `Either` as a `Left`.
*/
diff --git a/src/library/scala/util/Try.scala b/src/library/scala/util/Try.scala
index b0eae74043..b1b9965614 100644
--- a/src/library/scala/util/Try.scala
+++ b/src/library/scala/util/Try.scala
@@ -61,7 +61,7 @@ import scala.language.implicitConversions
* @author based on Twitter's original implementation in com.twitter.util.
* @since 2.10
*/
-sealed abstract class Try[+T] {
+sealed abstract class Try[+T] extends Product with Serializable {
/** Returns `true` if the `Try` is a `Failure`, `false` otherwise.
*/
@@ -75,16 +75,11 @@ sealed abstract class Try[+T] {
*
* ''Note:'': This will throw an exception if it is not a success and default throws an exception.
*/
- def getOrElse[U >: T](default: => U): U =
- if (isSuccess) get else default
+ def getOrElse[U >: T](default: => U): U
/** Returns this `Try` if it's a `Success` or the given `default` argument if this is a `Failure`.
*/
- def orElse[U >: T](default: => Try[U]): Try[U] =
- try if (isSuccess) this else default
- catch {
- case NonFatal(e) => Failure(e)
- }
+ def orElse[U >: T](default: => Try[U]): Try[U]
/** Returns the value from this `Success` or throws the exception if this is a `Failure`.
*/
@@ -108,6 +103,11 @@ sealed abstract class Try[+T] {
def map[U](f: T => U): Try[U]
/**
+ * Applies the given partial function to the value from this `Success` or returns this if this is a `Failure`.
+ */
+ def collect[U](pf: PartialFunction[T, U]): Try[U]
+
+ /**
* Converts this to a `Failure` if the predicate is not satisfied.
*/
def filter(p: T => Boolean): Try[T]
@@ -134,6 +134,7 @@ sealed abstract class Try[+T] {
* collection" contract even though it seems unlikely to matter much in a
* collection with max size 1.
*/
+ @deprecatedInheritance("You were never supposed to be able to extend this class.", "2.12")
class WithFilter(p: T => Boolean) {
def map[U](f: T => U): Try[U] = Try.this filter p map f
def flatMap[U](f: T => Try[U]): Try[U] = Try.this filter p flatMap f
@@ -145,18 +146,18 @@ sealed abstract class Try[+T] {
* Applies the given function `f` if this is a `Failure`, otherwise returns this if this is a `Success`.
* This is like `flatMap` for the exception.
*/
- def recoverWith[U >: T](f: PartialFunction[Throwable, Try[U]]): Try[U]
+ def recoverWith[U >: T](@deprecatedName('f) pf: PartialFunction[Throwable, Try[U]]): Try[U]
/**
* Applies the given function `f` if this is a `Failure`, otherwise returns this if this is a `Success`.
* This is like map for the exception.
*/
- def recover[U >: T](f: PartialFunction[Throwable, U]): Try[U]
+ def recover[U >: T](@deprecatedName('f) pf: PartialFunction[Throwable, U]): Try[U]
/**
* Returns `None` if this is a `Failure` or a `Some` containing the value if this is a `Success`.
*/
- def toOption: Option[T] = if (isSuccess) Some(get) else None
+ def toOption: Option[T]
/**
* Transforms a nested `Try`, ie, a `Try` of type `Try[Try[T]]`,
@@ -173,13 +174,31 @@ sealed abstract class Try[+T] {
/** Completes this `Try` by applying the function `f` to this if this is of type `Failure`, or conversely, by applying
* `s` if this is a `Success`.
*/
- def transform[U](s: T => Try[U], f: Throwable => Try[U]): Try[U] =
- try this match {
- case Success(v) => s(v)
- case Failure(e) => f(e)
- } catch {
- case NonFatal(e) => Failure(e)
- }
+ def transform[U](s: T => Try[U], f: Throwable => Try[U]): Try[U]
+
+ /**
+ * Returns `Left` with `Throwable` if this is a `Failure`, otherwise returns `Right` with `Success` value.
+ */
+ def toEither: Either[Throwable, T]
+
+ /**
+ * Applies `fa` if this is a `Failure` or `fb` if this is a `Success`.
+ * If `fb` is initially applied and throws an exception,
+ * then `fa` is applied with this exception.
+ *
+ * @example {{{
+ * val result: Try[Throwable, Int] = Try { string.toInt }
+ * log(result.fold(
+ * ex => "Operation failed with " + ex,
+ * v => "Operation produced value: " + v
+ * ))
+ * }}}
+ *
+ * @param fa the function to apply if this is a `Failure`
+ * @param fb the function to apply if this is a `Success`
+ * @return the results of applying the function
+ */
+ def fold[U](fa: Throwable => U, fb: T => U): U
}
@@ -192,57 +211,60 @@ object Try {
try Success(r) catch {
case NonFatal(e) => Failure(e)
}
-
}
final case class Failure[+T](exception: Throwable) extends Try[T] {
- def isFailure: Boolean = true
- def isSuccess: Boolean = false
- def recoverWith[U >: T](f: PartialFunction[Throwable, Try[U]]): Try[U] =
- try {
- if (f isDefinedAt exception) f(exception) else this
- } catch {
- case NonFatal(e) => Failure(e)
- }
- def get: T = throw exception
- def flatMap[U](f: T => Try[U]): Try[U] = this.asInstanceOf[Try[U]]
- def flatten[U](implicit ev: T <:< Try[U]): Try[U] = this.asInstanceOf[Try[U]]
- def foreach[U](f: T => U): Unit = ()
- def map[U](f: T => U): Try[U] = this.asInstanceOf[Try[U]]
- def filter(p: T => Boolean): Try[T] = this
- def recover[U >: T](rescueException: PartialFunction[Throwable, U]): Try[U] =
- try {
- if (rescueException isDefinedAt exception) {
- Try(rescueException(exception))
- } else this
- } catch {
- case NonFatal(e) => Failure(e)
- }
- def failed: Try[Throwable] = Success(exception)
+ override def isFailure: Boolean = true
+ override def isSuccess: Boolean = false
+ override def get: T = throw exception
+ override def getOrElse[U >: T](default: => U): U = default
+ override def orElse[U >: T](default: => Try[U]): Try[U] =
+ try default catch { case NonFatal(e) => Failure(e) }
+ override def flatMap[U](f: T => Try[U]): Try[U] = this.asInstanceOf[Try[U]]
+ override def flatten[U](implicit ev: T <:< Try[U]): Try[U] = this.asInstanceOf[Try[U]]
+ override def foreach[U](f: T => U): Unit = ()
+ override def transform[U](s: T => Try[U], f: Throwable => Try[U]): Try[U] =
+ try f(exception) catch { case NonFatal(e) => Failure(e) }
+ override def map[U](f: T => U): Try[U] = this.asInstanceOf[Try[U]]
+ override def collect[U](pf: PartialFunction[T, U]): Try[U] = this.asInstanceOf[Try[U]]
+ override def filter(p: T => Boolean): Try[T] = this
+ override def recover[U >: T](@deprecatedName('rescueException) pf: PartialFunction[Throwable, U]): Try[U] =
+ try { if (pf isDefinedAt exception) Success(pf(exception)) else this } catch { case NonFatal(e) => Failure(e) }
+ override def recoverWith[U >: T](@deprecatedName('f) pf: PartialFunction[Throwable, Try[U]]): Try[U] =
+ try { if (pf isDefinedAt exception) pf(exception) else this } catch { case NonFatal(e) => Failure(e) }
+ override def failed: Try[Throwable] = Success(exception)
+ override def toOption: Option[T] = None
+ override def toEither: Either[Throwable, T] = Left(exception)
+ override def fold[U](fa: Throwable => U, fb: T => U): U = fa(exception)
}
final case class Success[+T](value: T) extends Try[T] {
- def isFailure: Boolean = false
- def isSuccess: Boolean = true
- def recoverWith[U >: T](f: PartialFunction[Throwable, Try[U]]): Try[U] = this
- def get = value
- def flatMap[U](f: T => Try[U]): Try[U] =
- try f(value)
- catch {
- case NonFatal(e) => Failure(e)
- }
- def flatten[U](implicit ev: T <:< Try[U]): Try[U] = value
- def foreach[U](f: T => U): Unit = f(value)
- def map[U](f: T => U): Try[U] = Try[U](f(value))
- def filter(p: T => Boolean): Try[T] = {
+ override def isFailure: Boolean = false
+ override def isSuccess: Boolean = true
+ override def get = value
+ override def getOrElse[U >: T](default: => U): U = get
+ override def orElse[U >: T](default: => Try[U]): Try[U] = this
+ override def flatMap[U](f: T => Try[U]): Try[U] =
+ try f(value) catch { case NonFatal(e) => Failure(e) }
+ override def flatten[U](implicit ev: T <:< Try[U]): Try[U] = value
+ override def foreach[U](f: T => U): Unit = f(value)
+ override def transform[U](s: T => Try[U], f: Throwable => Try[U]): Try[U] = this flatMap s
+ override def map[U](f: T => U): Try[U] = Try[U](f(value))
+ override def collect[U](pf: PartialFunction[T, U]): Try[U] =
try {
- if (p(value)) this
+ if (pf isDefinedAt value) Success(pf(value))
else Failure(new NoSuchElementException("Predicate does not hold for " + value))
- } catch {
- case NonFatal(e) => Failure(e)
- }
- }
- def recover[U >: T](rescueException: PartialFunction[Throwable, U]): Try[U] = this
- def failed: Try[Throwable] = Failure(new UnsupportedOperationException("Success.failed"))
+ } catch { case NonFatal(e) => Failure(e) }
+ override def filter(p: T => Boolean): Try[T] =
+ try {
+ if (p(value)) this else Failure(new NoSuchElementException("Predicate does not hold for " + value))
+ } catch { case NonFatal(e) => Failure(e) }
+ override def recover[U >: T](@deprecatedName('rescueException) pf: PartialFunction[Throwable, U]): Try[U] = this
+ override def recoverWith[U >: T](@deprecatedName('f) pf: PartialFunction[Throwable, Try[U]]): Try[U] = this
+ override def failed: Try[Throwable] = Failure(new UnsupportedOperationException("Success.failed"))
+ override def toOption: Option[T] = Some(value)
+ override def toEither: Either[Throwable, T] = Right(value)
+ override def fold[U](fa: Throwable => U, fb: T => U): U =
+ try { fb(value) } catch { case NonFatal(e) => fa(e) }
}
diff --git a/src/manual/scala/man1/scalac.scala b/src/manual/scala/man1/scalac.scala
index c658fe89f8..3219b10293 100644
--- a/src/manual/scala/man1/scalac.scala
+++ b/src/manual/scala/man1/scalac.scala
@@ -152,12 +152,9 @@ object scalac extends Command {
CmdOption("sourcepath", Argument("path")),
"Specify location(s) of source files."),
Definition(
- CmdOptionBound("target:", "{jvm-1.5,jvm-1.6,jvm-1.7,jvm-1.8}"),
+ CmdOptionBound("target:", "{jvm-1.8}"),
SeqPara(
- Mono("\"jvm-1.5\"") & " target JVM 1.5 (deprecated),",
- Mono("\"jvm-1.6\"") & " target JVM 1.6 (default),",
- Mono("\"jvm-1.7\"") & " target JVM 1.7,",
- Mono("\"jvm-1.8\"") & " target JVM 1.8,")),
+ Mono("\"jvm-1.8\"") & " target JVM 1.8 (default)")),
Definition(
CmdOption("toolcp", Argument("path")),
"Add to the runner classpath."),
diff --git a/src/reflect/scala/reflect/api/Symbols.scala b/src/reflect/scala/reflect/api/Symbols.scala
index c01029d067..b7234ba47a 100644
--- a/src/reflect/scala/reflect/api/Symbols.scala
+++ b/src/reflect/scala/reflect/api/Symbols.scala
@@ -228,7 +228,7 @@ trait Symbols { self: Universe =>
throw new ScalaReflectionException(s"$this $msg")
}
- /** Used to provide a better error message for `asMethod`
+ /** Used to provide a better error message for `asMethod`.
*
* @group Tests
*/
@@ -257,7 +257,7 @@ trait Symbols { self: Universe =>
def isClass: Boolean = false
/** Does this symbol represent the definition of a class implicitly associated
- * with an object definition (module class in scala compiler parlance).
+ * with an object definition (module class in scala compiler parlance)?
* If yes, `isType` is also guaranteed to be true.
*
* Note to compiler developers: During the "mixin" phase, trait implementation class symbols
@@ -294,7 +294,7 @@ trait Symbols { self: Universe =>
/** For a class: the module or case class factory with the same name in the same package.
* For a module: the class with the same name in the same package.
- * For all others: NoSymbol
+ * For all others: NoSymbol.
*
* This API may return unexpected results for module classes, packages and package classes.
* Use `companion` instead in order to get predictable results.
@@ -345,7 +345,7 @@ trait Symbols { self: Universe =>
*/
def overrides: List[Symbol]
- /** The overloaded alternatives of this symbol
+ /** The overloaded alternatives of this symbol.
*
* @group Basics
*/
@@ -370,7 +370,7 @@ trait Symbols { self: Universe =>
/** Does this symbol represent a declaration or definition written in a source file as `private[this]`
* or generated in tree/symbol form with the combination of flags LOCAL and PRIVATE?
- * If yes, `isPrivate` is guaranteed to be true,
+ * If yes, `isPrivate` is guaranteed to be true.
*
* @group Tests
*/
@@ -678,7 +678,7 @@ trait Symbols { self: Universe =>
*/
def toTypeIn(site: Type): Type
- /** A type reference that refers to this type symbol
+ /** A type reference that refers to this type symbol.
* Note if symbol is a member of a class, one almost always is interested
* in `asTypeIn` with a site type instead.
*
@@ -727,7 +727,7 @@ trait Symbols { self: Universe =>
*/
def isExistential : Boolean
- /** For a polymorphic type, its type parameters, the empty list for all other types
+ /** For a polymorphic type, its type parameters, the empty list for all other types.
*
* @group Type
*/
@@ -756,12 +756,13 @@ trait Symbols { self: Universe =>
*/
def typeParams: List[Symbol]
- /** @see [[paramLists]] */
+ /** @see [[paramLists]]
+ *
+ * The name ending with "ss" indicates that the result type is a list of lists. */
@deprecated("Use `paramLists` instead", "2.11.0")
def paramss: List[List[Symbol]]
/** All parameter lists of the method.
- * The name ending with "ss" indicates that the result type is a list of lists.
*
* Can be used to distinguish nullary methods and methods with empty parameter lists.
* For a nullary method, returns the empty list (i.e. `List()`).
@@ -777,7 +778,7 @@ trait Symbols { self: Universe =>
*/
def isVarargs: Boolean
- /** The return type of the method
+ /** The return type of the method.
*
* @group Method
*/
@@ -911,7 +912,7 @@ trait Symbols { self: Universe =>
*/
def superPrefix(supertpe: Type): Type
- /** For a polymorphic class/trait, its type parameters, the empty list for all other classes/trait
+ /** For a polymorphic class/trait, its type parameters, the empty list for all other classes/trait.
*
* @group Class
*/
diff --git a/src/reflect/scala/reflect/internal/Mirrors.scala b/src/reflect/scala/reflect/internal/Mirrors.scala
index 0cbb976a98..0f0f16574e 100644
--- a/src/reflect/scala/reflect/internal/Mirrors.scala
+++ b/src/reflect/scala/reflect/internal/Mirrors.scala
@@ -180,7 +180,7 @@ trait Mirrors extends api.Mirrors {
def getPackageObject(fullname: String): ModuleSymbol = getPackageObject(newTermName(fullname))
def getPackageObject(fullname: TermName): ModuleSymbol =
- (getPackage(fullname).info member nme.PACKAGE) match {
+ (getPackage(fullname).packageObject) match {
case x: ModuleSymbol => x
case _ => MissingRequirementError.notFound("package object " + fullname)
}
@@ -191,15 +191,6 @@ trait Mirrors extends api.Mirrors {
def getPackageObjectIfDefined(fullname: TermName): Symbol =
wrapMissing(getPackageObject(fullname))
- final def getPackageObjectWithMember(pre: Type, sym: Symbol): Symbol = {
- // The owner of a symbol which requires package qualification may be the
- // package object iself, but it also could be any superclass of the package
- // object. In the latter case, we must go through the qualifier's info
- // to obtain the right symbol.
- if (sym.owner.isModuleClass) sym.owner.sourceModule // fast path, if the member is owned by a module class, that must be linked to the package object
- else pre member nme.PACKAGE // otherwise we have to findMember
- }
-
override def staticPackage(fullname: String): ModuleSymbol =
try ensurePackageSymbol(fullname.toString, getModuleOrClass(newTermNameCached(fullname)), allowModules = false)
catch { case mre: MissingRequirementError => throw new ScalaReflectionException(mre.msg) }
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index 63e2ca0dbe..26e3cf6d0b 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -111,6 +111,7 @@ trait StdNames {
val PACKAGE: NameType = "package"
val ROOT: NameType = "<root>"
val SPECIALIZED_SUFFIX: NameType = "$sp"
+ val CASE_ACCESSOR: NameType = "$access"
val NESTED_IN: String = "$nestedIn"
val NESTED_IN_ANON_CLASS: String = NESTED_IN + ANON_CLASS_NAME.toString.replace("$", "")
diff --git a/src/reflect/scala/reflect/internal/SymbolTable.scala b/src/reflect/scala/reflect/internal/SymbolTable.scala
index ef63078f90..b0145f8a89 100644
--- a/src/reflect/scala/reflect/internal/SymbolTable.scala
+++ b/src/reflect/scala/reflect/internal/SymbolTable.scala
@@ -332,7 +332,7 @@ abstract class SymbolTable extends macros.Universe
/** if there's a `package` member object in `pkgClass`, enter its members into it. */
def openPackageModule(pkgClass: Symbol) {
- val pkgModule = pkgClass.info.decl(nme.PACKAGEkw)
+ val pkgModule = pkgClass.packageObject
def fromSource = pkgModule.rawInfo match {
case ltp: SymLoader => ltp.fromSource
case _ => false
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index 285d59c5e2..478b1b9732 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -819,6 +819,12 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
def skipPackageObject: Symbol = this
+ /** The package object symbol corresponding to this package or package class symbol, or NoSymbol otherwise */
+ def packageObject: Symbol =
+ if (isPackageClass) tpe.packageObject
+ else if (isPackage) moduleClass.packageObject
+ else NoSymbol
+
/** If this is a constructor, its owner: otherwise this.
*/
final def skipConstructor: Symbol = if (isConstructor) owner else this
@@ -858,7 +864,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def isDeprecated = hasAnnotation(DeprecatedAttr)
def deprecationMessage = getAnnotation(DeprecatedAttr) flatMap (_ stringArg 0)
def deprecationVersion = getAnnotation(DeprecatedAttr) flatMap (_ stringArg 1)
- def deprecatedParamName = getAnnotation(DeprecatedNameAttr) flatMap (_ symbolArg 0)
+ def deprecatedParamName = getAnnotation(DeprecatedNameAttr) flatMap (_ symbolArg 0 orElse Some(nme.NO_NAME))
def hasDeprecatedInheritanceAnnotation
= hasAnnotation(DeprecatedInheritanceAttr)
def deprecatedInheritanceMessage
@@ -3378,13 +3384,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def implicitMembers: Scope = {
val tp = info
if ((implicitMembersCacheKey1 ne tp) || (implicitMembersCacheKey2 ne tp.decls.elems)) {
- // Skip a package object class, because the members are also in
- // the package and we wish to avoid spurious ambiguities as in pos/t3999.
- if (!isPackageObjectClass) {
- implicitMembersCacheValue = tp.implicitMembers
- implicitMembersCacheKey1 = tp
- implicitMembersCacheKey2 = tp.decls.elems
- }
+ implicitMembersCacheValue = tp.membersBasedOnFlags(BridgeFlags, IMPLICIT)
+ implicitMembersCacheKey1 = tp
+ implicitMembersCacheKey2 = tp.decls.elems
}
implicitMembersCacheValue
}
diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala
index b2248ad518..894038dd0a 100644
--- a/src/reflect/scala/reflect/internal/TreeGen.scala
+++ b/src/reflect/scala/reflect/internal/TreeGen.scala
@@ -191,8 +191,8 @@ abstract class TreeGen {
)
val pkgQualifier =
if (needsPackageQualifier) {
- val packageObject = rootMirror.getPackageObjectWithMember(qual.tpe, sym)
- Select(qual, nme.PACKAGE) setSymbol packageObject setType singleType(qual.tpe, packageObject)
+ val packageObject = qualsym.packageObject
+ Select(qual, nme.PACKAGE) setSymbol packageObject setType packageObject.typeOfThis
}
else qual
diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala
index 4657fa0000..7ad5fdf096 100644
--- a/src/reflect/scala/reflect/internal/TreeInfo.scala
+++ b/src/reflect/scala/reflect/internal/TreeInfo.scala
@@ -128,6 +128,7 @@ abstract class TreeInfo {
symOk(tree.symbol)
&& tree.symbol.isStable
&& !definitions.isByNameParamType(tree.tpe)
+ && !definitions.isByName(tree.symbol)
&& (allowVolatile || !tree.symbol.hasVolatileType) // TODO SPEC: not required by spec
)
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index f74d976b82..6ded3bcbe3 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -589,7 +589,12 @@ trait Types
def nonPrivateMembersAdmitting(admit: Long): Scope = membersBasedOnFlags(BridgeAndPrivateFlags & ~admit, 0)
/** A list of all implicit symbols of this type (defined or inherited) */
- def implicitMembers: Scope = membersBasedOnFlags(BridgeFlags, IMPLICIT)
+ def implicitMembers: Scope = {
+ typeSymbolDirect match {
+ case sym: ModuleClassSymbol => sym.implicitMembers
+ case _ => membersBasedOnFlags(BridgeFlags, IMPLICIT)
+ }
+ }
/** A list of all deferred symbols of this type (defined or inherited) */
def deferredMembers: Scope = membersBasedOnFlags(BridgeFlags, DEFERRED)
@@ -606,6 +611,8 @@ trait Types
def nonPrivateMember(name: Name): Symbol =
memberBasedOnName(name, BridgeAndPrivateFlags)
+ def packageObject: Symbol = member(nme.PACKAGE)
+
/** The non-private member with given name, admitting members with given flags `admit`.
* "Admitting" refers to the fact that members with a PRIVATE, BRIDGE, or VBRIDGE
* flag are usually excluded from findMember results, but supplying any of those flags
@@ -659,7 +666,7 @@ trait Types
)
if (trivial) this
else {
- val m = newAsSeenFromMap(pre.normalize, clazz)
+ val m = new AsSeenFromMap(pre.normalize, clazz)
val tp = m(this)
val tp1 = existentialAbstraction(m.capturedParams, tp)
@@ -1600,7 +1607,14 @@ trait Types
private var normalized: Type = _
private def normalizeImpl = {
// TODO see comments around def intersectionType and def merge
- def flatten(tps: List[Type]): List[Type] = tps flatMap { case RefinedType(parents, ds) if ds.isEmpty => flatten(parents) case tp => List(tp) }
+ // SI-8575 The dealias is needed here to keep subtyping transitive, example in run/t8575b.scala
+ def flatten(tps: List[Type]): List[Type] = {
+ def dealiasRefinement(tp: Type) = if (tp.dealias.isInstanceOf[RefinedType]) tp.dealias else tp
+ tps map dealiasRefinement flatMap {
+ case RefinedType(parents, ds) if ds.isEmpty => flatten(parents)
+ case tp => List(tp)
+ }
+ }
val flattened = flatten(parents).distinct
if (decls.isEmpty && hasLength(flattened, 1)) {
flattened.head
diff --git a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
index 1fc7aebab0..464bbad2cd 100644
--- a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
+++ b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
@@ -239,7 +239,6 @@ abstract class UnPickler {
if (missing.startsWith("scala.xml")) Some(("org.scala-lang.modules", "scala-xml"))
else if (missing.startsWith("scala.util.parsing")) Some(("org.scala-lang.modules", "scala-parser-combinators"))
else if (missing.startsWith("scala.swing")) Some(("org.scala-lang.modules", "scala-swing"))
- else if (missing.startsWith("scala.util.continuations")) Some(("org.scala-lang.plugins", "scala-continuations-library"))
else None
(module map { case (group, art) =>
diff --git a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala
index 15a87200f1..891fccb3e1 100644
--- a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala
+++ b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala
@@ -449,12 +449,15 @@ private[internal] trait TypeMaps {
(pre eq NoType) || (pre eq NoPrefix) || !isPossiblePrefix(clazz)
)
- def newAsSeenFromMap(pre: Type, clazz: Symbol): AsSeenFromMap =
- new AsSeenFromMap(pre, clazz)
+ @deprecated("Use new AsSeenFromMap instead", "2.12.0")
+ final def newAsSeenFromMap(pre: Type, clazz: Symbol): AsSeenFromMap = new AsSeenFromMap(pre, clazz)
/** A map to compute the asSeenFrom method.
*/
- class AsSeenFromMap(seenFromPrefix: Type, seenFromClass: Symbol) extends TypeMap with KeepOnlyTypeConstraints {
+ class AsSeenFromMap(seenFromPrefix0: Type, seenFromClass: Symbol) extends TypeMap with KeepOnlyTypeConstraints {
+ private val seenFromPrefix: Type = if (seenFromPrefix0.typeSymbolDirect.hasPackageFlag && !seenFromClass.hasPackageFlag)
+ seenFromPrefix0.packageObject.typeOfThis
+ else seenFromPrefix0
// Some example source constructs relevant in asSeenFrom:
//
// object CaptureThis {
diff --git a/src/reflect/scala/reflect/internal/transform/Erasure.scala b/src/reflect/scala/reflect/internal/transform/Erasure.scala
index 707972242a..5a03c1eeaa 100644
--- a/src/reflect/scala/reflect/internal/transform/Erasure.scala
+++ b/src/reflect/scala/reflect/internal/transform/Erasure.scala
@@ -282,8 +282,17 @@ trait Erasure {
}
object boxingErasure extends ScalaErasureMap {
+ private var boxPrimitives = true
+
+ override def applyInArray(tp: Type): Type = {
+ val saved = boxPrimitives
+ boxPrimitives = false
+ try super.applyInArray(tp)
+ finally boxPrimitives = saved
+ }
+
override def eraseNormalClassRef(tref: TypeRef) =
- if (isPrimitiveValueClass(tref.sym)) boxedClass(tref.sym).tpe
+ if (boxPrimitives && isPrimitiveValueClass(tref.sym)) boxedClass(tref.sym).tpe
else super.eraseNormalClassRef(tref)
override def eraseDerivedValueClassRef(tref: TypeRef) =
super.eraseNormalClassRef(tref)
diff --git a/src/scaladoc/scala/tools/nsc/doc/base/MemberLookupBase.scala b/src/scaladoc/scala/tools/nsc/doc/base/MemberLookupBase.scala
index cc217d2f80..f853df0484 100755
--- a/src/scaladoc/scala/tools/nsc/doc/base/MemberLookupBase.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/base/MemberLookupBase.scala
@@ -62,15 +62,15 @@ trait MemberLookupBase {
syms.flatMap { case (sym, owner) =>
// reconstruct the original link
def linkName(sym: Symbol) = {
- def nameString(s: Symbol) = s.nameString + (if ((s.isModule || s.isModuleClass) && !s.isPackage) "$" else "")
- val packageSuffix = if (sym.isPackage) ".package" else ""
+ def nameString(s: Symbol) = s.nameString + (if ((s.isModule || s.isModuleClass) && !s.hasPackageFlag) "$" else "")
+ val packageSuffix = if (sym.hasPackageFlag) ".package" else ""
sym.ownerChain.reverse.filterNot(isRoot(_)).map(nameString(_)).mkString(".") + packageSuffix
}
- if (sym.isClass || sym.isModule || sym.isTrait || sym.isPackage)
+ if (sym.isClass || sym.isModule || sym.isTrait || sym.hasPackageFlag)
findExternalLink(sym, linkName(sym))
- else if (owner.isClass || owner.isModule || owner.isTrait || owner.isPackage)
+ else if (owner.isClass || owner.isModule || owner.isTrait || owner.hasPackageFlag)
findExternalLink(sym, linkName(owner) + "@" + externalSignature(sym))
else
None
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala
index 81036b4908..99f989aadf 100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala
@@ -147,7 +147,7 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
{ if (tpl.linearizationTemplates.isEmpty && tpl.conversions.isEmpty) NodeSeq.Empty else
{
if (!tpl.linearizationTemplates.isEmpty)
- <div id="ancestors">
+ <div class="ancestors">
<span class="filtertype">Inherited<br/>
</span>
<ol id="linearization">
@@ -157,7 +157,7 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
else NodeSeq.Empty
} ++ {
if (!tpl.conversions.isEmpty)
- <div id="ancestors">
+ <div class="ancestors">
<span class="filtertype">Implicitly<br/>
</span>
<ol id="implicits"> {
@@ -171,7 +171,7 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
</div>
else NodeSeq.Empty
} ++
- <div id="ancestors">
+ <div class="ancestors">
<span class="filtertype"></span>
<ol>
<li class="hideall out"><span>Hide All</span></li>
@@ -204,28 +204,28 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
}
{ if (absValueMembers.isEmpty) NodeSeq.Empty else
- <div id="values" class="values members">
+ <div class="values members">
<h3>Abstract Value Members</h3>
<ol>{ absValueMembers map (memberToHtml(_, tpl)) }</ol>
</div>
}
{ if (concValueMembers.isEmpty) NodeSeq.Empty else
- <div id="values" class="values members">
+ <div class="values members">
<h3>{ if (absValueMembers.isEmpty) "Value Members" else "Concrete Value Members" }</h3>
<ol>{ concValueMembers map (memberToHtml(_, tpl)) }</ol>
</div>
}
{ if (shadowedImplicitMembers.isEmpty) NodeSeq.Empty else
- <div id="values" class="values members">
+ <div class="values members">
<h3>Shadowed Implicit Value Members</h3>
<ol>{ shadowedImplicitMembers map (memberToHtml(_, tpl)) }</ol>
</div>
}
{ if (deprValueMembers.isEmpty) NodeSeq.Empty else
- <div id="values" class="values members">
+ <div class="values members">
<h3>Deprecated Value Members</h3>
<ol>{ deprValueMembers map (memberToHtml(_, tpl)) }</ol>
</div>
@@ -290,13 +290,19 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
}
def memberToHtml(mbr: MemberEntity, inTpl: DocTemplateEntity): NodeSeq = {
+ // Sometimes it's same, do we need signatureCompat still?
+ val sig = if (mbr.signature == mbr.signatureCompat) {
+ <a id={ mbr.signature }/>
+ } else {
+ <a id={ mbr.signature }/><a id={ mbr.signatureCompat }/>
+ }
+
val memberComment = memberToCommentHtml(mbr, inTpl, isSelf = false)
<li name={ mbr.definitionName } visbl={ if (mbr.visibility.isProtected) "prt" else "pub" }
data-isabs={ mbr.isAbstract.toString }
fullComment={ if(memberComment.filter(_.label=="div").isEmpty) "no" else "yes" }
group={ mbr.group }>
- <a id={ mbr.signature }/>
- <a id={ mbr.signatureCompat }/>
+ { sig }
{ signature(mbr, isSelf = false) }
{ memberComment }
</li>
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala
index 320a8e23b2..4c0ba32856 100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala
@@ -364,7 +364,7 @@ class DotDiagramGenerator(settings: doc.Settings, dotRunner: DotRunner) extends
// add an id and class attribute to the SVG element
case Elem(prefix, "svg", attribs, scope, child @ _*) => {
val klass = if (isInheritanceDiagram) "class-diagram" else "package-diagram"
- Elem(prefix, "svg", attribs, scope, child map(x => transform(x)) : _*) %
+ Elem(prefix, "svg", attribs, scope, true, child map(x => transform(x)) : _*) %
new UnprefixedAttribute("id", "graph" + counter, Null) %
new UnprefixedAttribute("class", klass, Null)
}
@@ -378,7 +378,7 @@ class DotDiagramGenerator(settings: doc.Settings, dotRunner: DotRunner) extends
// assign id and class attributes to edges and nodes:
// the id attribute generated by dot has the format: "{class}|{id}"
case g @ Elem(prefix, "g", attribs, scope, children @ _*) if (List("edge", "node").contains((g \ "@class").toString)) => {
- var res = new Elem(prefix, "g", attribs, scope, (children map(x => transform(x))): _*)
+ var res = new Elem(prefix, "g", attribs, scope, true, (children map(x => transform(x))): _*)
val dotId = (g \ "@id").toString
if (dotId.count(_ == '|') == 1) {
val Array(klass, id) = dotId.toString.split("\\|")
@@ -395,11 +395,11 @@ class DotDiagramGenerator(settings: doc.Settings, dotRunner: DotRunner) extends
val imageNode = <image xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href={ ("./lib/" + kind + "_diagram.png") } width="16px" height="16px" preserveAspectRatio="xMinYMin meet" x={ xposition.get.toString } y={ yposition.get.toString }/>
val anchorNode = (g \ "a") match {
case Seq(Elem(prefix, "a", attribs, scope, children @ _*)) =>
- transform(new Elem(prefix, "a", attribs, scope, (children ++ imageNode): _*))
+ transform(new Elem(prefix, "a", attribs, scope, true, (children ++ imageNode): _*))
case _ =>
g \ "a"
}
- res = new Elem(prefix, "g", attribs, scope, anchorNode: _*)
+ res = new Elem(prefix, "g", attribs, scope, true, anchorNode: _*)
DiagramStats.addFixedImage()
}
}
@@ -413,7 +413,7 @@ class DotDiagramGenerator(settings: doc.Settings, dotRunner: DotRunner) extends
scala.xml.Text("")
// apply recursively
case Elem(prefix, label, attribs, scope, child @ _*) =>
- Elem(prefix, label, attribs, scope, child map(x => transform(x)) : _*)
+ Elem(prefix, label, attribs, scope, true, child map(x => transform(x)) : _*)
case x => x
}
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css
index e84d7c1ca6..f158aa7309 100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css
+++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css
@@ -218,7 +218,7 @@ dl.attributes > dd {
height: 18px;
}
-#values ol li:last-child {
+.values ol li:last-child {
margin-bottom: 5px;
}
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js
index 798a2d430b..c1e3010834 100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js
+++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js
@@ -147,19 +147,19 @@ $(document).ready(function(){
filter();
});
- $("#mbrsel > div[id=ancestors] > ol > li.hideall").click(function() {
+ $("#mbrsel > div.ancestors > ol > li.hideall").click(function() {
$("#linearization li.in").removeClass("in").addClass("out");
$("#linearization li:first").removeClass("out").addClass("in");
$("#implicits li.in").removeClass("in").addClass("out");
- if ($(this).hasClass("out") && $("#mbrsel > div[id=ancestors] > ol > li.showall").hasClass("in")) {
+ if ($(this).hasClass("out") && $("#mbrsel > div.ancestors > ol > li.showall").hasClass("in")) {
$(this).removeClass("out").addClass("in");
- $("#mbrsel > div[id=ancestors] > ol > li.showall").removeClass("in").addClass("out");
+ $("#mbrsel > div.ancestors > ol > li.showall").removeClass("in").addClass("out");
}
filter();
})
- $("#mbrsel > div[id=ancestors] > ol > li.showall").click(function() {
+ $("#mbrsel > div.ancestors > ol > li.showall").click(function() {
var filteredLinearization =
$("#linearization li.out").filter(function() {
return ! isHiddenClass($(this).attr("name"));
@@ -172,9 +172,9 @@ $(document).ready(function(){
});
filteredImplicits.removeClass("out").addClass("in");
- if ($(this).hasClass("out") && $("#mbrsel > div[id=ancestors] > ol > li.hideall").hasClass("in")) {
+ if ($(this).hasClass("out") && $("#mbrsel > div.ancestors > ol > li.hideall").hasClass("in")) {
$(this).removeClass("out").addClass("in");
- $("#mbrsel > div[id=ancestors] > ol > li.hideall").removeClass("in").addClass("out");
+ $("#mbrsel > div.ancestors > ol > li.hideall").removeClass("in").addClass("out");
}
filter();
@@ -275,7 +275,7 @@ function orderAlpha() {
$("#order > ol > li.group").removeClass("in").addClass("out");
$("#template > div.parent").hide();
$("#template > div.conversion").hide();
- $("#mbrsel > div[id=ancestors]").show();
+ $("#mbrsel > div.ancestors").show();
filter();
};
@@ -285,7 +285,7 @@ function orderInherit() {
$("#order > ol > li.group").removeClass("in").addClass("out");
$("#template > div.parent").show();
$("#template > div.conversion").show();
- $("#mbrsel > div[id=ancestors]").hide();
+ $("#mbrsel > div.ancestors").hide();
filter();
};
@@ -295,7 +295,7 @@ function orderGroup() {
$("#order > ol > li.inherit").removeClass("in").addClass("out");
$("#template > div.parent").hide();
$("#template > div.conversion").hide();
- $("#mbrsel > div[id=ancestors]").show();
+ $("#mbrsel > div.ancestors").show();
filter();
};
@@ -350,7 +350,7 @@ function initInherit() {
}
});
- $("#values > ol > li").each(function(){
+ $(".values > ol > li").each(function(){
var mbr = $(this);
this.mbrText = mbr.find("> .fullcomment .cmt").text();
var qualName = mbr.attr("name");
diff --git a/src/scaladoc/scala/tools/nsc/doc/model/MemberLookup.scala b/src/scaladoc/scala/tools/nsc/doc/model/MemberLookup.scala
index 64eb1adbea..20aaab29fc 100644
--- a/src/scaladoc/scala/tools/nsc/doc/model/MemberLookup.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/model/MemberLookup.scala
@@ -40,7 +40,7 @@ trait MemberLookup extends base.MemberLookupBase {
override def findExternalLink(sym: Symbol, name: String): Option[LinkToExternal] = {
val sym1 =
if (sym == AnyClass || sym == AnyRefClass || sym == AnyValClass || sym == NothingClass) ListClass
- else if (sym.isPackage)
+ else if (sym.hasPackageFlag)
/* Get package object which has associatedFile ne null */
sym.info.member(newTermName("package"))
else sym
diff --git a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala
index 3cbcbc433e..178af3d4ba 100644
--- a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala
@@ -93,10 +93,10 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
trait TemplateImpl extends EntityImpl with TemplateEntity {
override def qualifiedName: String =
if (inTemplate == null || inTemplate.isRootPackage) name else optimize(inTemplate.qualifiedName + "." + name)
- def isPackage = sym.isPackage
+ def isPackage = sym.hasPackageFlag
def isTrait = sym.isTrait
def isClass = sym.isClass && !sym.isTrait
- def isObject = sym.isModule && !sym.isPackage
+ def isObject = sym.isModule && !sym.hasPackageFlag
def isCaseClass = sym.isCaseClass
def isRootPackage = false
def selfType = if (sym.thisSym eq sym) None else Some(makeType(sym.thisSym.typeOfThis, this))
@@ -254,7 +254,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
def valueParams: List[List[ValueParam]] = Nil /** TODO, these are now only computed for DocTemplates */
def parentTypes =
- if (sym.isPackage || sym == AnyClass) List() else {
+ if (sym.hasPackageFlag || sym == AnyClass) List() else {
val tps = (this match {
case a: AliasType => sym.tpe.dealias.parents
case a: AbstractType => sym.info.bounds match {
@@ -665,7 +665,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
s != EmptyPackage && s != RootPackage
}
})
- else if (bSym.isPackage) // (2)
+ else if (bSym.hasPackageFlag) // (2)
if (settings.skipPackage(makeQualifiedName(bSym)))
None
else
@@ -778,7 +778,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
Some(new MemberTemplateImpl(bSym, inTpl) with AliasImpl with AliasType {
override def isAliasType = true
})
- else if (!modelFinished && (bSym.isPackage || templateShouldDocument(bSym, inTpl)))
+ else if (!modelFinished && (bSym.hasPackageFlag || templateShouldDocument(bSym, inTpl)))
modelCreation.createTemplate(bSym, inTpl)
else
None
diff --git a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala
index 2b7e2506d4..ea72fa6095 100644
--- a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala
@@ -94,7 +94,7 @@ trait ModelFactoryTypeSupport {
LinkToMember(bMbr, oTpl)
case _ =>
val name = makeQualifiedName(bSym)
- if (!bSym.owner.isPackage)
+ if (!bSym.owner.hasPackageFlag)
Tooltip(name)
else
findExternalLink(bSym, name).getOrElse (
diff --git a/src/scaladoc/scala/tools/nsc/doc/model/TreeFactory.scala b/src/scaladoc/scala/tools/nsc/doc/model/TreeFactory.scala
index 86a7a67160..c1228e8735 100755
--- a/src/scaladoc/scala/tools/nsc/doc/model/TreeFactory.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/model/TreeFactory.scala
@@ -49,7 +49,7 @@ trait TreeFactory { thisTreeFactory: ModelFactory with TreeFactory =>
case _ =>
}
else if (asym.isTerm && asym.owner.isClass){
- if (asym.isSetter) asym = asym.getter(asym.owner)
+ if (asym.isSetter) asym = asym.getterIn(asym.owner)
makeTemplate(asym.owner) match {
case docTmpl: DocTemplateImpl =>
val mbrs: Option[MemberImpl] = findMember(asym, docTmpl)
diff --git a/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala b/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala
index 44d8886e4e..b300752a34 100644
--- a/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala
@@ -177,7 +177,7 @@ trait DiagramDirectiveParser {
def warning(message: String) = {
// we need the position from the package object (well, ideally its comment, but yeah ...)
- val sym = if (template.sym.isPackage) template.sym.info.member(global.nme.PACKAGE) else template.sym
+ val sym = if (template.sym.hasPackageFlag) template.sym.packageObject else template.sym
assert((sym != global.NoSymbol) || (sym == global.rootMirror.RootPackage))
global.reporter.warning(sym.pos, message)
}
diff --git a/test/files/filters b/test/files/filters
index 51a7507848..e91ca0eb36 100644
--- a/test/files/filters
+++ b/test/files/filters
@@ -1,6 +1,7 @@
#
#Java HotSpot(TM) 64-Bit Server VM warning: Failed to reserve shared memory (errno = 28).
Java HotSpot\(TM\) .* warning:
+OpenJDK .* warning:
# Hotspot receiving VM options through the $_JAVA_OPTIONS
# env variable outputs them on stderr
Picked up _JAVA_OPTIONS:
diff --git a/test/files/jvm/actor-exceptions.check b/test/files/jvm/actor-exceptions.check
deleted file mode 100644
index d86bac9de5..0000000000
--- a/test/files/jvm/actor-exceptions.check
+++ /dev/null
@@ -1 +0,0 @@
-OK
diff --git a/test/files/jvm/actor-exceptions.scala b/test/files/jvm/actor-exceptions.scala
deleted file mode 100644
index bdd983a0e8..0000000000
--- a/test/files/jvm/actor-exceptions.scala
+++ /dev/null
@@ -1,67 +0,0 @@
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
-import scala.actors.{Actor, Exit}
-import Actor._
-
-case class MyException(text: String) extends Exception {
- override def fillInStackTrace() = this
-}
-
-case class MyOtherException(text: String) extends Exception {
- override def fillInStackTrace() = this
-}
-
-object Master extends Actor {
- trapExit = true
- def act() {
- try {
- link(Slave)
- Slave.start()
- for (i <- 0 until 10) Slave ! A
- react {
- case Exit(from, reason) =>
- println("OK")
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
-}
-
-object Slave extends Actor {
- override def toString = "Slave"
- override def exceptionHandler: PartialFunction[Exception, Unit] = {
- case MyException(text) =>
- case other if !other.isInstanceOf[scala.util.control.ControlThrowable] => super.exceptionHandler(other)
- }
- def act() {
- try {
- var cnt = 0
- loop {
- react {
- case A =>
- cnt += 1
- if (cnt % 2 != 0) throw MyException("problem")
- if (cnt == 10) {
- throw MyOtherException("unhandled")
- }
- }
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] &&
- !e.isInstanceOf[MyException] &&
- !e.isInstanceOf[MyOtherException] =>
- e.printStackTrace()
- }
- }
-}
-
-case object A
-
- def main(args: Array[String]) {
- Master.start()
- }
-}
diff --git a/test/files/jvm/actor-executor.check b/test/files/jvm/actor-executor.check
deleted file mode 100644
index bdbdb5c6a2..0000000000
--- a/test/files/jvm/actor-executor.check
+++ /dev/null
@@ -1,20 +0,0 @@
-Two: OK
-One: OK
-Two: OK
-One: OK
-Two: OK
-One: OK
-Two: OK
-One: OK
-Two: OK
-One: OK
-Two: OK
-One: OK
-Two: OK
-One: OK
-Two: OK
-One: OK
-Two: OK
-One: OK
-Two: OK
-One: OK
diff --git a/test/files/jvm/actor-executor.scala b/test/files/jvm/actor-executor.scala
deleted file mode 100644
index 0fc28b4d85..0000000000
--- a/test/files/jvm/actor-executor.scala
+++ /dev/null
@@ -1,78 +0,0 @@
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
-import java.util.concurrent.Executors
-import scala.actors.{Actor, SchedulerAdapter}
-import Actor._
-
-trait AdaptedActor extends Actor {
- override def scheduler =
- Test.scheduler
-}
-
-object One extends AdaptedActor {
- def act() {
- try {
- Two.start()
- var i = 0
- loopWhile (i < 10000) {
- i += 1
- Two ! 'MsgForTwo
- react {
- case 'MsgForOne =>
- if (i % 1000 == 0)
- println("One: OK")
- if (i == 10000)
- Test.executor.shutdown()
- }
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
-}
-
-object Two extends AdaptedActor {
- def act() {
- try {
- var i = 0
- loopWhile (i < 10000) {
- i += 1
- react {
- case 'MsgForTwo =>
- if (i % 1000 == 0)
- println("Two: OK")
- One ! 'MsgForOne
- }
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
-}
-
- val executor =
- Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors())
-
- val scheduler =
- new SchedulerAdapter {
- def execute(block: => Unit) {
- val task = new Runnable {
- def run() { block }
- }
- try {
- executor.execute(task)
- } catch {
- case ree: java.util.concurrent.RejectedExecutionException =>
- task.run()
- }
- }
- }
-
- def main(args: Array[String]) {
- One.start()
- }
-}
diff --git a/test/files/jvm/actor-executor2.check b/test/files/jvm/actor-executor2.check
deleted file mode 100644
index da78f45836..0000000000
--- a/test/files/jvm/actor-executor2.check
+++ /dev/null
@@ -1,21 +0,0 @@
-Two: OK
-One: OK
-Two: OK
-One: OK
-Two: OK
-One: OK
-Two: OK
-One: OK
-Two: OK
-One: OK
-Two: OK
-One: OK
-Two: OK
-One: OK
-Two: OK
-One: OK
-Two: OK
-One: OK
-Two: OK
-One: OK
-One exited
diff --git a/test/files/jvm/actor-executor2.scala b/test/files/jvm/actor-executor2.scala
deleted file mode 100644
index 5badf2ae7e..0000000000
--- a/test/files/jvm/actor-executor2.scala
+++ /dev/null
@@ -1,92 +0,0 @@
-
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
-import scala.actors.{Actor, SchedulerAdapter, Exit}
-import Actor._
-import java.util.concurrent.{Executors, RejectedExecutionException}
-
-object One extends AdaptedActor {
- def act() {
- try {
- Two.start()
- var i = 0
- loopWhile (i < Test.NUM_MSG) {
- i += 1
- Two ! 'MsgForTwo
- react {
- case 'MsgForOne =>
- if (i % (Test.NUM_MSG/10) == 0)
- println("One: OK")
- }
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
-}
-
-object Two extends AdaptedActor {
- def act() {
- try {
- var i = 0
- loopWhile (i < Test.NUM_MSG) {
- i += 1
- react {
- case 'MsgForTwo =>
- if (i % (Test.NUM_MSG/10) == 0)
- println("Two: OK")
- One ! 'MsgForOne
- }
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
-}
-
-trait AdaptedActor extends Actor {
- override def scheduler =
- Test.scheduler
-}
-
- val NUM_MSG = 100000
-
- val executor =
- Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors())
-
- val scheduler =
- new SchedulerAdapter {
- def execute(block: => Unit) {
- val task = new Runnable {
- def run() { block }
- }
- try {
- executor.execute(task)
- } catch {
- case ree: RejectedExecutionException =>
- task.run() // run task on current thread
- }
- }
- }
-
- def main(args: Array[String]) {
- try {
- self.trapExit = true
- link(One)
- One.start()
-
- receive {
- case Exit(from, reason) =>
- println("One exited")
- Test.executor.shutdown()
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
-}
diff --git a/test/files/jvm/actor-executor3.check b/test/files/jvm/actor-executor3.check
deleted file mode 100644
index bdbdb5c6a2..0000000000
--- a/test/files/jvm/actor-executor3.check
+++ /dev/null
@@ -1,20 +0,0 @@
-Two: OK
-One: OK
-Two: OK
-One: OK
-Two: OK
-One: OK
-Two: OK
-One: OK
-Two: OK
-One: OK
-Two: OK
-One: OK
-Two: OK
-One: OK
-Two: OK
-One: OK
-Two: OK
-One: OK
-Two: OK
-One: OK
diff --git a/test/files/jvm/actor-executor3.scala b/test/files/jvm/actor-executor3.scala
deleted file mode 100644
index f8b57d84b3..0000000000
--- a/test/files/jvm/actor-executor3.scala
+++ /dev/null
@@ -1,66 +0,0 @@
-
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
-import scala.actors.Actor
-import scala.actors.scheduler.ExecutorScheduler
-import java.util.concurrent.Executors
-
-object One extends AdaptedActor {
- def act() {
- try {
- Two.start()
- var i = 0
- loopWhile (i < Test.NUM_MSG) {
- i += 1
- Two ! 'MsgForTwo
- react {
- case 'MsgForOne =>
- if (i % (Test.NUM_MSG/10) == 0)
- println("One: OK")
- }
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
-}
-
-object Two extends AdaptedActor {
- def act() {
- try {
- var i = 0
- loopWhile (i < Test.NUM_MSG) {
- i += 1
- react {
- case 'MsgForTwo =>
- if (i % (Test.NUM_MSG/10) == 0)
- println("Two: OK")
- One ! 'MsgForOne
- }
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
-}
-
-trait AdaptedActor extends Actor {
- override def scheduler =
- Test.scheduler
-}
-
- val NUM_MSG = 100000
-
- val executor =
- Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors())
-
- val scheduler = ExecutorScheduler(executor)
-
- def main(args: Array[String]) {
- One.start()
- }
-}
diff --git a/test/files/jvm/actor-getstate.check b/test/files/jvm/actor-getstate.check
deleted file mode 100644
index 2c94e48371..0000000000
--- a/test/files/jvm/actor-getstate.check
+++ /dev/null
@@ -1,2 +0,0 @@
-OK
-OK
diff --git a/test/files/jvm/actor-getstate.scala b/test/files/jvm/actor-getstate.scala
deleted file mode 100644
index 425efbe5e6..0000000000
--- a/test/files/jvm/actor-getstate.scala
+++ /dev/null
@@ -1,87 +0,0 @@
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
- import scala.actors.{Reactor, Actor, TIMEOUT}
- import Actor._
-
- def assert(cond: => Boolean, hint: String) {
- if (!cond)
- println("FAIL ["+hint+"]")
- }
-
- def expectActorState(a: Reactor[T] forSome { type T }, s: Actor.State.Value) {
- var done = false
- var i = 0
- while (!done) {
- i = i + 1
- if (i == 10) { // only wait for 2 seconds total
- println("FAIL ["+a+": expected "+s+"]")
- done = true
- }
-
- Thread.sleep(200)
- if (a.getState == s) // success
- done = true
- }
- }
-
- def main(args: Array[String]) {
- actor {
- val a = new Reactor[Any] {
- def act() {
- assert(getState == Actor.State.Runnable, "runnable1")
- react {
- case 'go =>
- println("OK")
- }
- }
- }
- expectActorState(a, Actor.State.New)
-
- a.start()
- expectActorState(a, Actor.State.Suspended)
-
- a ! 'go
- expectActorState(a, Actor.State.Terminated)
-
- val b = new Actor {
- def act() {
- assert(getState == Actor.State.Runnable, "runnable2: "+getState)
- react {
- case 'go =>
- reactWithin(100000) {
- case TIMEOUT =>
- case 'go =>
- receive {
- case 'go =>
- }
- receiveWithin(100000) {
- case TIMEOUT =>
- case 'go =>
- println("OK")
- }
- }
- }
- }
- }
- expectActorState(b, Actor.State.New)
-
- b.start()
- expectActorState(b, Actor.State.Suspended)
-
- b ! 'go
- expectActorState(b, Actor.State.TimedSuspended)
-
- b ! 'go
- expectActorState(b, Actor.State.Blocked)
-
- b ! 'go
- expectActorState(b, Actor.State.TimedBlocked)
-
- b ! 'go
- expectActorState(b, Actor.State.Terminated)
- }
- }
-
-}
diff --git a/test/files/jvm/actor-link-getstate.check b/test/files/jvm/actor-link-getstate.check
deleted file mode 100644
index 9755447320..0000000000
--- a/test/files/jvm/actor-link-getstate.check
+++ /dev/null
@@ -1,2 +0,0 @@
-Done
-Terminated
diff --git a/test/files/jvm/actor-link-getstate.scala b/test/files/jvm/actor-link-getstate.scala
deleted file mode 100644
index d8b8ada1e6..0000000000
--- a/test/files/jvm/actor-link-getstate.scala
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
- import scala.actors.{Actor, Exit}
- import scala.actors.Actor._
-
-case class MyException(text: String) extends Exception(text) {
- override def fillInStackTrace() = this
-}
-
-object Slave extends Actor {
- def act() {
- try {
- loop {
- react {
- case 'doWork =>
- Console.out.println("Done")
- reply('done)
- }
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
-}
-
-object Master extends Actor {
- override def toString = "Master"
- def act() {
- try {
- link(Slave)
- Slave ! 'doWork
- react {
- case 'done =>
- throw new MyException("Master crashed")
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
-}
-
-
- def main(args: Array[String]) {
- actor {
- try {
- self.trapExit = true
- link(Slave)
- Slave.start()
- Master.start()
- react {
- case Exit(from, reason) if (from == Slave) =>
- Console.out.println(Slave.getState)
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
- }
-
-}
diff --git a/test/files/jvm/actor-looping.check b/test/files/jvm/actor-looping.check
deleted file mode 100644
index a6f5c2e73a..0000000000
--- a/test/files/jvm/actor-looping.check
+++ /dev/null
@@ -1,5 +0,0 @@
-received A
-received A
-received A
-received A
-received last A
diff --git a/test/files/jvm/actor-looping.scala b/test/files/jvm/actor-looping.scala
deleted file mode 100644
index 7bc6f1e5c5..0000000000
--- a/test/files/jvm/actor-looping.scala
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
- import scala.actors.Actor._
- case object A
-
- def main(args: Array[String]) {
- val a = actor {
- try {
- var cnt = 0
- loop {
- react {
- case A =>
- cnt += 1
- if (cnt % 2 != 0) continue
- if (cnt < 10)
- println("received A")
- else {
- println("received last A")
- exit()
- }
- }
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
-
- for (i <- 0 until 10) a ! A
- }
-}
diff --git a/test/files/jvm/actor-normal-exit.check b/test/files/jvm/actor-normal-exit.check
deleted file mode 100644
index 6865f83b90..0000000000
--- a/test/files/jvm/actor-normal-exit.check
+++ /dev/null
@@ -1,2 +0,0 @@
-Done
-slave exited for reason 'normal
diff --git a/test/files/jvm/actor-normal-exit.scala b/test/files/jvm/actor-normal-exit.scala
deleted file mode 100644
index 90495866e2..0000000000
--- a/test/files/jvm/actor-normal-exit.scala
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
- import scala.actors.{Actor, Exit}
- object Master extends Actor {
- trapExit = true
- def act() {
- try {
- Slave.start()
- react {
- case Exit(from, reason) =>
- println("slave exited for reason " + reason)
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
- }
-
- object Slave extends Actor {
- def act() {
- try {
- link(Master)
- println("Done")
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
- }
-
- def main(args: Array[String]) {
- Master.start()
- }
-}
diff --git a/test/files/jvm/actor-receivewithin.check b/test/files/jvm/actor-receivewithin.check
deleted file mode 100644
index a6a3e88c61..0000000000
--- a/test/files/jvm/actor-receivewithin.check
+++ /dev/null
@@ -1,16 +0,0 @@
-'msg
-'msg
-'msg
-'msg
-'msg
-TIMEOUT
-TIMEOUT
-TIMEOUT
-TIMEOUT
-TIMEOUT
-'msg2
-'msg2
-'msg2
-'msg2
-'msg2
-TIMEOUT
diff --git a/test/files/jvm/actor-receivewithin.scala b/test/files/jvm/actor-receivewithin.scala
deleted file mode 100644
index 5982462502..0000000000
--- a/test/files/jvm/actor-receivewithin.scala
+++ /dev/null
@@ -1,72 +0,0 @@
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
-import scala.actors.{Actor, TIMEOUT}
-
-object A extends Actor {
- def act() {
- receive {
- case 'done =>
- var cnt = 0
- while (cnt < 500) {
- cnt += 1
- receiveWithin (0) {
- case 'msg =>
- if (cnt % 100 == 0)
- println("'msg")
- case TIMEOUT =>
- // should not happen
- println("FAIL1")
- }
- }
- cnt = 0
- while (cnt < 500) {
- cnt += 1
- receiveWithin (0) {
- case 'msg =>
- // should not happen
- println("FAIL2")
- case TIMEOUT =>
- if (cnt % 100 == 0)
- println("TIMEOUT")
- }
- }
- B ! 'next
- receive { case 'done => }
- cnt = 0
- while (cnt < 501) {
- cnt += 1
- receiveWithin (500) {
- case 'msg2 =>
- if (cnt % 100 == 0)
- println("'msg2")
- case TIMEOUT =>
- println("TIMEOUT")
- }
- }
- }
- }
-}
-
-object B extends Actor {
- def act() {
- A.start()
- for (_ <- 1 to 500) {
- A ! 'msg
- }
- A ! 'done
- receive {
- case 'next =>
- for (_ <- 1 to 500) {
- A ! 'msg2
- }
- A ! 'done
- }
- }
-}
-
- def main(args:Array[String]) {
- B.start()
- }
-}
diff --git a/test/files/jvm/actor-sync-send-timeout.scala b/test/files/jvm/actor-sync-send-timeout.scala
deleted file mode 100644
index 66a0b0a6ff..0000000000
--- a/test/files/jvm/actor-sync-send-timeout.scala
+++ /dev/null
@@ -1,48 +0,0 @@
-@deprecated("Suppress warnings", since="2.11")
-object Test {
-import scala.actors.Actor
-
-/* This test is a regression test for SI-4759.
- */
- val Runs = 5
-
- def main(args: Array[String]) = {
- var i = 0
- while (i < Runs) {
- i += 1
- A1 ! 1
- Thread.sleep(500)
- }
- //println("done sending to A1")
- }
-
-object A2 extends Actor {
- this.start()
- def act() {
- loop {
- react {
- case 'stop =>
- //println("A2 exiting")
- exit()
- case _ =>
- }
- }
- }
-}
-
-object A1 extends Actor {
- this.start()
- def act() {
- var i = 0
- loopWhile(i < Test.Runs) {
- i += 1
- react {
- case any =>
- A2 !? (500, any)
- if (i == Test.Runs)
- A2 ! 'stop
- }
- }
- }
-}
-}
diff --git a/test/files/jvm/actor-termination.check b/test/files/jvm/actor-termination.check
deleted file mode 100644
index e3f44d8b18..0000000000
--- a/test/files/jvm/actor-termination.check
+++ /dev/null
@@ -1,2 +0,0 @@
-I'm going to make you wait.
-Ok, I'm done.
diff --git a/test/files/jvm/actor-termination.scala b/test/files/jvm/actor-termination.scala
deleted file mode 100644
index 4a6bf92d48..0000000000
--- a/test/files/jvm/actor-termination.scala
+++ /dev/null
@@ -1,19 +0,0 @@
-
-/* Test that an actor that hasn't finished prevents termination */
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
- import scala.actors.Actor
- def main(args: Array[String]) {
- Actor.actor {
- try {
- println("I'm going to make you wait.")
- Thread.sleep(5000)
- println("Ok, I'm done.")
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
- }
-}
diff --git a/test/files/jvm/actor-uncaught-exception.check b/test/files/jvm/actor-uncaught-exception.check
deleted file mode 100644
index 2c94e48371..0000000000
--- a/test/files/jvm/actor-uncaught-exception.check
+++ /dev/null
@@ -1,2 +0,0 @@
-OK
-OK
diff --git a/test/files/jvm/actor-uncaught-exception.scala b/test/files/jvm/actor-uncaught-exception.scala
deleted file mode 100644
index c28ad2fa3c..0000000000
--- a/test/files/jvm/actor-uncaught-exception.scala
+++ /dev/null
@@ -1,64 +0,0 @@
-@deprecated("Suppress warnings", since="2.11")
-object Test {
-import scala.actors.{Actor, Exit}
-
-class MyException(msg: String) extends Exception(msg) {
- override def fillInStackTrace() = this
-}
-
-
- case object StartError extends Actor {
- def act() {
- try {
- throw new MyException("I don't want to run!")
- } catch {
- case e: Throwable if (!e.isInstanceOf[scala.util.control.ControlThrowable] &&
- !e.isInstanceOf[MyException]) =>
- e.printStackTrace()
- }
- }
- }
-
- case object MessageError extends Actor {
- def act() {
- try {
- react {
- case _ => throw new MyException("No message for me!")
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
- }
-
- case object Supervisor extends Actor {
- def act() {
- try {
- trapExit = true
- link(StartError)
- link(MessageError)
- StartError.start()
- MessageError.start()
-
- Actor.loop {
- react {
- case Exit(actor, reason) =>
- println("OK")
- if (actor == StartError)
- MessageError ! 'ping
- else
- exit()
- }
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
- }
-
- def main(args: Array[String]) {
- Supervisor.start()
- }
-}
diff --git a/test/files/jvm/actor-uncaught-exception2.check b/test/files/jvm/actor-uncaught-exception2.check
deleted file mode 100644
index a54f374aed..0000000000
--- a/test/files/jvm/actor-uncaught-exception2.check
+++ /dev/null
@@ -1,2 +0,0 @@
-UncaughtException(StartError,None,None,Test$MyException: I don't want to run!)
-UncaughtException(MessageError,Some('ping),Some(Supervisor),Test$MyException: No message for me!)
diff --git a/test/files/jvm/actor-uncaught-exception2.scala b/test/files/jvm/actor-uncaught-exception2.scala
deleted file mode 100644
index 8327b4e19d..0000000000
--- a/test/files/jvm/actor-uncaught-exception2.scala
+++ /dev/null
@@ -1,63 +0,0 @@
-@deprecated("Suppress warnings", since="2.11")
-object Test {
-import scala.actors.{Actor, Exit, Debug}
-
-class MyException(msg: String) extends Exception(msg) {
- override def fillInStackTrace() = this
-}
-
- case object StartError extends Actor {
- def act() {
- try {
- throw new MyException("I don't want to run!")
- } catch {
- case e: Throwable if (!e.isInstanceOf[scala.util.control.ControlThrowable] &&
- !e.isInstanceOf[MyException]) =>
- e.printStackTrace()
- }
- }
- }
-
- case object MessageError extends Actor {
- def act() {
- try {
- react {
- case _ => throw new MyException("No message for me!")
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
- }
-
- case object Supervisor extends Actor {
- def act() {
- try {
- trapExit = true
- link(StartError)
- link(MessageError)
- StartError.start()
- MessageError.start()
-
- Actor.loop {
- react {
- case Exit(actor, reason) =>
- println(reason)
- if (actor == StartError)
- MessageError ! 'ping
- else
- exit()
- }
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
- }
-
- def main(args: Array[String]) {
- Supervisor.start()
- }
-}
diff --git a/test/files/jvm/daemon-actor-termination.check b/test/files/jvm/daemon-actor-termination.check
deleted file mode 100644
index b2ff72fd0b..0000000000
--- a/test/files/jvm/daemon-actor-termination.check
+++ /dev/null
@@ -1,2 +0,0 @@
-MSG1
-MSG2
diff --git a/test/files/jvm/daemon-actor-termination.scala b/test/files/jvm/daemon-actor-termination.scala
deleted file mode 100644
index 9bac6340ba..0000000000
--- a/test/files/jvm/daemon-actor-termination.scala
+++ /dev/null
@@ -1,40 +0,0 @@
-
-/* Test that a daemon Actor that hasn't finished does not prevent termination */
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
-
- import scala.actors.{Actor, DaemonActor}
- class MyDaemon extends DaemonActor {
- def act() {
- try {
- react {
- case 'hello =>
- println("MSG1")
- reply(())
- react {
- case 'bye =>
- println("done")
- }
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
- }
-
- def main(args: Array[String]) {
- val daemon = new MyDaemon
- daemon.start()
- Actor.actor {
- try {
- daemon !? 'hello
- println("MSG2")
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
- }
-}
diff --git a/test/files/jvm/future-alarm.check b/test/files/jvm/future-alarm.check
deleted file mode 100644
index 01a87d1c4c..0000000000
--- a/test/files/jvm/future-alarm.check
+++ /dev/null
@@ -1,20 +0,0 @@
-OK
-OK
-OK
-OK
-OK
-OK
-OK
-OK
-OK
-OK
-OK
-OK
-OK
-OK
-OK
-OK
-OK
-OK
-OK
-OK
diff --git a/test/files/jvm/future-alarm.scala b/test/files/jvm/future-alarm.scala
deleted file mode 100644
index 3e71fa681c..0000000000
--- a/test/files/jvm/future-alarm.scala
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
- import scala.actors.Futures
- def main(args: Array[String]) {
- try {
- for (i <- 1 to 100000) {
- Futures.alarm(0)
- if (i % 10000 == 0)
- println("OK")
- }
- for (_ <- 1 to 10) {
- val ft = Futures.alarm(100)
- ft()
- println("OK")
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
-}
diff --git a/test/files/jvm/future-awaitall-zero.check b/test/files/jvm/future-awaitall-zero.check
deleted file mode 100644
index d86bac9de5..0000000000
--- a/test/files/jvm/future-awaitall-zero.check
+++ /dev/null
@@ -1 +0,0 @@
-OK
diff --git a/test/files/jvm/future-awaitall-zero.scala b/test/files/jvm/future-awaitall-zero.scala
deleted file mode 100644
index 56f4bab16f..0000000000
--- a/test/files/jvm/future-awaitall-zero.scala
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
- import scala.actors.Futures._
- import scala.actors.Actor._
- def main(args: Array[String]) {
- try {
- val ft1 = future { reactWithin(10000) {
- case _ => println("FAIL")
- } }
-
- val ft2 = future { reactWithin(20000) {
- case _ => println("FAIL")
- } }
-
- val res = awaitAll(0, ft1, ft2)
- println("OK")
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
-}
diff --git a/test/files/jvm/future-spec.check b/test/files/jvm/future-spec.check
index df1629dd7e..5c80aa5586 100644
--- a/test/files/jvm/future-spec.check
+++ b/test/files/jvm/future-spec.check
@@ -1 +1 @@
-warning: there was one deprecation warning; re-run with -deprecation for details
+warning: there were 21 deprecation warnings; re-run with -deprecation for details
diff --git a/test/files/jvm/future-spec/FutureTests.scala b/test/files/jvm/future-spec/FutureTests.scala
index a290af9cd3..6b34d5bfaa 100644
--- a/test/files/jvm/future-spec/FutureTests.scala
+++ b/test/files/jvm/future-spec/FutureTests.scala
@@ -17,6 +17,19 @@ class FutureTests extends MinimalScalaTest {
case "NoReply" => Promise[String]().future
}
+ def fail(msg: String): Nothing = throw new AssertionError(msg)
+
+ def ECNotUsed[T](f: ExecutionContext => T): T = {
+ val p = Promise[Runnable]()
+ val unusedEC: ExecutionContext = new ExecutionContext {
+ def execute(r: Runnable) = p.success(r)
+ def reportFailure(t: Throwable): Unit = p.failure(t)
+ }
+ val t = f(unusedEC)
+ assert(p.future.value == None, "Future executed logic!")
+ t
+ }
+
val defaultTimeout = 5 seconds
/* future specification */
@@ -68,6 +81,60 @@ class FutureTests extends MinimalScalaTest {
}
}
+ "Futures" should {
+ "have proper toString representations" in {
+ import ExecutionContext.Implicits.global
+ val s = 5
+ val f = new Exception("foo")
+ val t = Try(throw f)
+
+ val expectFailureString = "Future(Failure("+f+"))"
+ val expectSuccessString = "Future(Success(5))"
+ val expectNotCompleteString = "Future(<not completed>)"
+
+ Future.successful(s).toString mustBe expectSuccessString
+ Future.failed(f).toString mustBe expectFailureString
+ Future.fromTry(t).toString mustBe expectFailureString
+ val p = Promise[Int]()
+ p.toString mustBe expectNotCompleteString
+ Promise[Int]().success(s).toString mustBe expectSuccessString
+ Promise[Int]().failure(f).toString mustBe expectFailureString
+ Await.ready(Future { throw f }, 2000 millis).toString mustBe expectFailureString
+ Await.ready(Future { s }, 2000 millis).toString mustBe expectSuccessString
+
+ Future.never.toString mustBe "Future(<never>)"
+ Future.unit.toString mustBe "Future(Success(()))"
+ }
+
+ "have proper const representation for success" in {
+ val s = "foo"
+ val f = Future.successful(s)
+
+ ECNotUsed(ec => f.onFailure({ case _ => fail("onFailure should not have been called") })(ec))
+ assert( ECNotUsed(ec => f.recover({ case _ => fail("recover should not have been called")})(ec)) eq f)
+ assert( ECNotUsed(ec => f.recoverWith({ case _ => fail("flatMap should not have been called")})(ec)) eq f)
+ assert(f.fallbackTo(f) eq f, "Future.fallbackTo must be the same instance as Future.fallbackTo")
+ }
+
+ "have proper const representation for failure" in {
+ val e = new Exception("foo")
+ val f = Future.failed[Future[String]](e)
+
+ assert(f.mapTo[String] eq f, "Future.mapTo must be the same instance as Future.mapTo")
+ assert(f.zip(f) eq f, "Future.zip must be the same instance as Future.zip")
+ assert(f.flatten eq f, "Future.flatten must be the same instance as Future.flatten")
+ assert(f.failed eq f, "Future.failed must be the same instance as Future.failed")
+
+ ECNotUsed(ec => f.foreach(_ => fail("foreach should not have been called"))(ec))
+ ECNotUsed(ec => f.onSuccess({ case _ => fail("onSuccess should not have been called") })(ec))
+ assert( ECNotUsed(ec => f.map(_ => fail("map should not have been called"))(ec)) eq f)
+ assert( ECNotUsed(ec => f.flatMap(_ => fail("flatMap should not have been called"))(ec)) eq f)
+ assert( ECNotUsed(ec => f.filter(_ => fail("filter should not have been called"))(ec)) eq f)
+ assert( ECNotUsed(ec => f.collect({ case _ => fail("collect should not have been called")})(ec)) eq f)
+ assert( ECNotUsed(ec => f.zipWith(f)({ (_,_) => fail("zipWith should not have been called")})(ec)) eq f)
+ }
+ }
+
"The Future companion object" should {
"call ExecutionContext.prepare on apply" in {
val p = Promise[Boolean]()
@@ -85,6 +152,49 @@ class FutureTests extends MinimalScalaTest {
Await.result(f, defaultTimeout) mustBe ("foo")
Await.result(p.future, defaultTimeout) mustBe (true)
}
+
+ "have a unit member representing an already completed Future containing Unit" in {
+ assert(Future.unit ne null, "Future.unit must not be null")
+ assert(Future.unit eq Future.unit, "Future.unit must be the same instance as Future.unit")
+ assert(Future.unit.isCompleted, "Future.unit must already be completed")
+ assert(Future.unit.value.get == Success(()), "Future.unit must contain a Success(())")
+ }
+
+ "have a never member representing a never completed Future of Nothing" in {
+
+ val test: Future[Nothing] = Future.never
+
+ //Verify stable identifier
+ test match {
+ case Future.`never` =>
+ case _ => fail("Future.never did not match Future.`never`")
+ }
+
+ assert(test eq Future.never, "Future.never must be the same instance as Future.never")
+ assert(test ne null, "Future.never must not be null")
+ assert(!test.isCompleted && test.value.isEmpty, "Future.never must never be completed")
+ assert(test.failed eq test)
+ assert(test.asInstanceOf[Future[Future[Nothing]]].flatten eq test)
+ assert(test.zip(test) eq test)
+ assert(test.fallbackTo(test) eq test)
+ assert(test.mapTo[String] eq test)
+
+ ECNotUsed(ec => test.foreach(_ => fail("foreach should not have been called"))(ec))
+ ECNotUsed(ec => test.onSuccess({ case _ => fail("onSuccess should not have been called") })(ec))
+ ECNotUsed(ec => test.onFailure({ case _ => fail("onFailure should not have been called") })(ec))
+ ECNotUsed(ec => test.onComplete({ case _ => fail("onComplete should not have been called") })(ec))
+ ECNotUsed(ec => test.transform(identity, identity)(ec) eq test)
+ ECNotUsed(ec => test.transform(identity)(ec) eq test)
+ ECNotUsed(ec => test.transformWith(_ => fail("transformWith should not have been called"))(ec) eq test)
+ ECNotUsed(ec => test.map(identity)(ec) eq test)
+ ECNotUsed(ec => test.flatMap(_ => fail("flatMap should not have been called"))(ec) eq test)
+ ECNotUsed(ec => test.filter(_ => fail("filter should not have been called"))(ec) eq test)
+ ECNotUsed(ec => test.collect({ case _ => fail("collect should not have been called")})(ec) eq test)
+ ECNotUsed(ec => test.recover({ case _ => fail("recover should not have been called")})(ec) eq test)
+ ECNotUsed(ec => test.recoverWith({ case _ => fail("recoverWith should not have been called")})(ec) eq test)
+ ECNotUsed(ec => test.andThen({ case _ => fail("andThen should not have been called")})(ec) eq test)
+ ECNotUsed(ec => test.zipWith(test)({ (_,_) => fail("zipWith should not have been called")})(ec) eq test)
+ }
}
"The default ExecutionContext" should {
@@ -218,6 +328,142 @@ class FutureTests extends MinimalScalaTest {
} mustBe (r)
}
+ "transform results to results" in {
+ val f1 = Future.successful("foo").transform(_.map(_.toUpperCase))
+ val f2 = Future("bar").transform(_.map(_.toUpperCase))
+ Await.result(f1, defaultTimeout) mustBe "FOO"
+ Await.result(f2, defaultTimeout) mustBe "BAR"
+ }
+
+ "transform failures to failures" in {
+ val initial = new Exception("Initial")
+ val expected1 = new Exception("Expected1")
+ val expected2 = new Exception("Expected2")
+ val f1 = Future(throw initial) transform {
+ case Failure(`initial`) => Failure(expected1)
+ case x => x
+ }
+ val f2 = Future.failed(initial) transform {
+ case Failure(`initial`) => Failure(expected2)
+ case x => x
+ }
+
+ intercept[Exception] { Await.result(f1, defaultTimeout) } mustBe expected1
+ intercept[Exception] { Await.result(f2, defaultTimeout) } mustBe expected2
+ }
+
+ "transform failures to results" in {
+ val initial1 = new Exception("Initial1")
+ val initial2 = new Exception("Initial2")
+ val f1 = Future.failed[String](initial1) transform {
+ case Failure(`initial1`) => Success("foo")
+ case x => x
+ }
+ val f2 = Future[String](throw initial2) transform {
+ case Failure(`initial2`) => Success("bar")
+ case x => x
+ }
+ Await.result(f1, defaultTimeout) mustBe "foo"
+ Await.result(f2, defaultTimeout) mustBe "bar"
+ }
+
+ "transform results to failures" in {
+ val expected1 = new Exception("Expected1")
+ val expected2 = new Exception("Expected2")
+ val expected3 = new Exception("Expected3")
+ val f1 = Future.successful("foo") transform {
+ case Success("foo") => Failure(expected1)
+ case x => x
+ }
+ val f2 = Future("bar") transform {
+ case Success("bar") => Failure(expected2)
+ case x => x
+ }
+ val f3 = Future("bar") transform {
+ case Success("bar") => throw expected3
+ case x => x
+ }
+ intercept[Exception] { Await.result(f1, defaultTimeout) } mustBe expected1
+ intercept[Exception] { Await.result(f2, defaultTimeout) } mustBe expected2
+ intercept[Exception] { Await.result(f3, defaultTimeout) } mustBe expected3
+ }
+
+ "transformWith results" in {
+ val f1 = Future.successful("foo").transformWith {
+ case Success(r) => Future(r.toUpperCase)
+ case f @ Failure(_) => Future.fromTry(f)
+ }
+ val f2 = Future("bar").transformWith {
+ case Success(r) => Future(r.toUpperCase)
+ case f @ Failure(_) => Future.fromTry(f)
+ }
+ Await.result(f1, defaultTimeout) mustBe "FOO"
+ Await.result(f2, defaultTimeout) mustBe "BAR"
+ }
+
+ "transformWith failures" in {
+ val initial = new Exception("Initial")
+ val expected1 = new Exception("Expected1")
+ val expected2 = new Exception("Expected2")
+ val expected3 = new Exception("Expected3")
+
+ val f1 = Future[Int](throw initial).transformWith {
+ case Failure(`initial`) => Future failed expected1
+ case x => Future fromTry x
+ }
+ val f2 = Future.failed[Int](initial).transformWith {
+ case Failure(`initial`) => Future failed expected2
+ case x => Future fromTry x
+ }
+ val f3 = Future[Int](throw initial).transformWith {
+ case Failure(`initial`) => throw expected3
+ case x => Future fromTry x
+ }
+
+ intercept[Exception] { Await.result(f1, defaultTimeout) } mustBe expected1
+ intercept[Exception] { Await.result(f2, defaultTimeout) } mustBe expected2
+ intercept[Exception] { Await.result(f3, defaultTimeout) } mustBe expected3
+ }
+
+ "transformWith failures to future success" in {
+ val initial = new Exception("Initial")
+ val f1 = Future.failed[String](initial).transformWith {
+ case Failure(`initial`) => Future("FOO")
+ case _ => Future failed initial
+ }
+ val f2 = Future[String](throw initial).transformWith {
+ case Failure(`initial`) => Future("BAR")
+ case _ => Future failed initial
+ }
+ Await.result(f1, defaultTimeout) mustBe "FOO"
+ Await.result(f2, defaultTimeout) mustBe "BAR"
+ }
+
+ "transformWith results to future failures" in {
+ val initial = new Exception("Initial")
+ val expected1 = new Exception("Expected1")
+ val expected2 = new Exception("Expected2")
+ val expected3 = new Exception("Expected3")
+
+ val f1 = Future[String]("FOO") transformWith {
+ case Success("FOO") => Future failed expected1
+ case _ => Future successful "FOO"
+ }
+ val f2 = Future.successful("FOO") transformWith {
+ case Success("FOO") => Future failed expected2
+ case _ => Future successful "FOO"
+ }
+ val f3 = Future.successful("FOO") transformWith {
+ case Success("FOO") => throw expected3
+ case _ => Future successful "FOO"
+ }
+
+
+ intercept[Exception] { Await.result(f1, defaultTimeout) } mustBe expected1
+ intercept[Exception] { Await.result(f2, defaultTimeout) } mustBe expected2
+ intercept[Exception] { Await.result(f3, defaultTimeout) } mustBe expected3
+ }
+
"andThen like a boss" in {
val q = new java.util.concurrent.LinkedBlockingQueue[Int]
for (i <- 1 to 1000) {
@@ -281,6 +527,33 @@ class FutureTests extends MinimalScalaTest {
Await.result(successful, timeout) mustBe (("foo", "foo"))
}
+ "zipWith" in {
+ val timeout = 10000 millis
+ val f = new IllegalStateException("test")
+ intercept[IllegalStateException] {
+ val failed = Future.failed[String](f).zipWith(Future.successful("foo")) { _ -> _ }
+ Await.result(failed, timeout)
+ } mustBe (f)
+
+ intercept[IllegalStateException] {
+ val failed = Future.successful("foo").zipWith(Future.failed[String](f)) { _ -> _ }
+ Await.result(failed, timeout)
+ } mustBe (f)
+
+ intercept[IllegalStateException] {
+ val failed = Future.failed[String](f).zipWith(Future.failed[String](f)) { _ -> _ }
+ Await.result(failed, timeout)
+ } mustBe (f)
+
+ val successful = Future.successful("foo").zipWith(Future.successful("foo")) { _ -> _ }
+ Await.result(successful, timeout) mustBe (("foo", "foo"))
+
+ val failure = Future.successful("foo").zipWith(Future.successful("foo")) { (_,_) => throw f }
+ intercept[IllegalStateException] {
+ Await.result(failure, timeout)
+ } mustBe (f)
+ }
+
"fold" in {
val timeout = 10000 millis
def async(add: Int, wait: Int) = Future {
diff --git a/test/files/jvm/future-termination.check b/test/files/jvm/future-termination.check
deleted file mode 100644
index dc335465d4..0000000000
--- a/test/files/jvm/future-termination.check
+++ /dev/null
@@ -1 +0,0 @@
-I can't wait that long, bye.
diff --git a/test/files/jvm/future-termination.scala b/test/files/jvm/future-termination.scala
deleted file mode 100644
index 90ea336ce8..0000000000
--- a/test/files/jvm/future-termination.scala
+++ /dev/null
@@ -1,21 +0,0 @@
-
-/* Test that unevaluated futures do not prevent program termination */
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
- import scala.actors.Futures
- def main(args: Array[String]) {
- try {
- val meaningOfLife = Futures.future {
- Thread.sleep(5000) // pretend this is a harder problem than it is
- println("I have the answer!")
- 42
- }
- println("I can't wait that long, bye.")
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
-}
diff --git a/test/files/jvm/reactor-exceptionOnSend.check b/test/files/jvm/reactor-exceptionOnSend.check
deleted file mode 100644
index 45d62e26a7..0000000000
--- a/test/files/jvm/reactor-exceptionOnSend.check
+++ /dev/null
@@ -1,2 +0,0 @@
-receiver handles exception
-process
diff --git a/test/files/jvm/reactor-exceptionOnSend.scala b/test/files/jvm/reactor-exceptionOnSend.scala
deleted file mode 100644
index 6d79fc9d13..0000000000
--- a/test/files/jvm/reactor-exceptionOnSend.scala
+++ /dev/null
@@ -1,58 +0,0 @@
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
-import scala.actors.Reactor
-import scala.actors.Actor._
-
-case class MyException(text: String) extends Exception(text)
-
-object A extends Reactor[Any] {
- override def exceptionHandler = {
- case MyException(text) =>
- println("receiver handles exception")
- }
-
- def guard(): Boolean =
- if (state == 0) {
- state = 1
- throw MyException("illegal state")
- } else
- true
-
- var state = 0
-
- def act() {
- try {
- loop {
- react {
- case 'hello if guard() =>
- println("process")
- exit()
- }
- }
- } catch {
- case e: Throwable if (!e.isInstanceOf[scala.util.control.ControlThrowable] &&
- !e.isInstanceOf[MyException]) =>
- e.printStackTrace()
- }
- }
-}
-
-object B extends Reactor[Any] {
- def act() {
- try {
- A.start()
- A ! 'hello
- A ! 'hello
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
-}
-
- def main(args: Array[String]) {
- B.start()
- }
-}
diff --git a/test/files/jvm/reactor-producer-consumer.check b/test/files/jvm/reactor-producer-consumer.check
deleted file mode 100644
index d971cea19e..0000000000
--- a/test/files/jvm/reactor-producer-consumer.check
+++ /dev/null
@@ -1,10 +0,0 @@
-42
-42
-42
-42
-42
-42
-42
-42
-42
-42
diff --git a/test/files/jvm/reactor-producer-consumer.scala b/test/files/jvm/reactor-producer-consumer.scala
deleted file mode 100644
index ec34febe01..0000000000
--- a/test/files/jvm/reactor-producer-consumer.scala
+++ /dev/null
@@ -1,97 +0,0 @@
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
- import scala.actors.Reactor
- case class Stop()
- case class Get(from: Reactor[Any])
- case class Put(x: Int)
-
- class UnboundedBuffer extends Reactor[Any] {
- def act() {
- try {
- react {
- case Stop() =>
- case Get(from) =>
- val consumer = from
- react {
- case msg @ Put(x) =>
- consumer ! x
- act()
- }
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
- }
-
- class Producer(buf: UnboundedBuffer, n: Int, delay: Long, parent: Reactor[Any]) extends Reactor[Any] {
- def act() {
- try {
- var i = 0
- while (i < n) {
- i += 1
- if (delay > 0) Thread.sleep(delay)
- buf ! Put(42)
- }
- parent ! Stop()
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
- }
-
- class Consumer(buf: UnboundedBuffer, n: Int, delay: Long, parent: Reactor[Any]) extends Reactor[Any] {
- val step = n / 10
- var i = 0
- def act() {
- try {
- if (i < n) {
- i += 1
- if (delay > 0) Thread.sleep(delay)
- buf ! Get(this)
- react {
- case res =>
- if (i % step == 0)
- println(res)
- act()
- }
- } else {
- parent ! Stop()
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
- }
-
- def main(args: Array[String]) {
- val parent = new Reactor[Any] {
- def act() {
- try {
- val buffer = new UnboundedBuffer
- buffer.start()
- val producer = new Producer(buffer, 10000, 0, this)
- producer.start()
- val consumer = new Consumer(buffer, 10000, 0, this)
- consumer.start()
- react {
- case Stop() =>
- react {
- case Stop() =>
- buffer ! Stop()
- }
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
- }
- parent.start()
- }
-}
diff --git a/test/files/jvm/reactor.check b/test/files/jvm/reactor.check
deleted file mode 100644
index 7b16085797..0000000000
--- a/test/files/jvm/reactor.check
+++ /dev/null
@@ -1,22 +0,0 @@
-Pong: ping 0
-Ping: pong
-Pong: ping 10000
-Ping: pong
-Pong: ping 20000
-Ping: pong
-Pong: ping 30000
-Ping: pong
-Pong: ping 40000
-Ping: pong
-Pong: ping 50000
-Ping: pong
-Pong: ping 60000
-Ping: pong
-Pong: ping 70000
-Ping: pong
-Pong: ping 80000
-Ping: pong
-Pong: ping 90000
-Ping: pong
-Ping: stop
-Pong: stop
diff --git a/test/files/jvm/reactor.scala b/test/files/jvm/reactor.scala
deleted file mode 100644
index 91ded27f07..0000000000
--- a/test/files/jvm/reactor.scala
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * Ping pong example for Reactor.
- *
- * @author Philipp Haller
- */
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
-
-import scala.actors.Reactor
-
-case class Ping(from: Reactor[Any])
-case object Pong
-case object Stop
-
- def main(args: Array[String]) {
- val pong = new PongActor
- val ping = new PingActor(100000, pong)
- ping.start
- pong.start
- }
-
-class PingActor(count: Int, pong: Reactor[Any]) extends Reactor[Any] {
- def act() {
- try {
- var pingsLeft = count - 1
- pong ! Ping(this)
- loop {
- react {
- case Pong =>
- if (pingsLeft % 10000 == 0)
- println("Ping: pong")
- if (pingsLeft > 0) {
- pong ! Ping(this)
- pingsLeft -= 1
- } else {
- println("Ping: stop")
- pong ! Stop
- exit()
- }
- }
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
-}
-
-class PongActor extends Reactor[Any] {
- def act() {
- try {
- var pongCount = 0
- loop {
- react {
- case Ping(from) =>
- if (pongCount % 10000 == 0)
- println("Pong: ping "+pongCount)
- from ! Pong
- pongCount += 1
- case Stop =>
- println("Pong: stop")
- exit()
- }
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
-}
-}
diff --git a/test/files/jvm/replyablereactor.check b/test/files/jvm/replyablereactor.check
deleted file mode 100644
index 0944b17279..0000000000
--- a/test/files/jvm/replyablereactor.check
+++ /dev/null
@@ -1,5 +0,0 @@
-'hello
-'hello
-'hello
-'hello
-'hello
diff --git a/test/files/jvm/replyablereactor.scala b/test/files/jvm/replyablereactor.scala
deleted file mode 100644
index 4c4e13d9ab..0000000000
--- a/test/files/jvm/replyablereactor.scala
+++ /dev/null
@@ -1,59 +0,0 @@
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
-import scala.actors.ReplyReactor
-
-class MyActor extends ReplyReactor {
- def act() {
- try {
- loop {
- react {
- case 'hello =>
- sender ! 'hello
- case 'stop =>
- exit()
- }
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
-}
-
- def main(args: Array[String]) {
- val a = new MyActor
- a.start()
-
- val b = new ReplyReactor {
- def act() {
- try {
- react {
- case r: MyActor =>
- var i = 0
- loop {
- i += 1
- val ft = r !! 'hello
- ft.inputChannel.react {
- case msg =>
- if (i % 10000 == 0)
- println(msg)
- if (i >= 50000) {
- r ! 'stop
- exit()
- }
- }
- }
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
- }
- b.start()
-
- b ! a
- }
-}
diff --git a/test/files/jvm/replyablereactor2.check b/test/files/jvm/replyablereactor2.check
deleted file mode 100644
index 0944b17279..0000000000
--- a/test/files/jvm/replyablereactor2.check
+++ /dev/null
@@ -1,5 +0,0 @@
-'hello
-'hello
-'hello
-'hello
-'hello
diff --git a/test/files/jvm/replyablereactor2.scala b/test/files/jvm/replyablereactor2.scala
deleted file mode 100644
index 21f33cce56..0000000000
--- a/test/files/jvm/replyablereactor2.scala
+++ /dev/null
@@ -1,58 +0,0 @@
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
-import scala.actors._
-import scala.actors.Actor._
-
-class MyActor extends ReplyReactor {
- def act() {
- try {
- loop {
- react {
- case 'hello =>
- sender ! 'hello
- case 'stop =>
- exit()
- }
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
-}
-
- def main(args: Array[String]) {
- val a = new MyActor
- a.start()
-
- val b = new Reactor[Any] {
- def act() {
- try {
- react {
- case r: MyActor =>
- var i = 0
- loop {
- i += 1
- val ft = r !! 'hello
- val msg = ft()
- if (i % 10000 == 0)
- println(msg)
- if (i >= 50000) {
- r ! 'stop
- exit()
- }
- }
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
- }
- b.start()
-
- b ! a
- }
-}
diff --git a/test/files/jvm/replyablereactor3.check b/test/files/jvm/replyablereactor3.check
deleted file mode 100644
index 0944b17279..0000000000
--- a/test/files/jvm/replyablereactor3.check
+++ /dev/null
@@ -1,5 +0,0 @@
-'hello
-'hello
-'hello
-'hello
-'hello
diff --git a/test/files/jvm/replyablereactor3.scala b/test/files/jvm/replyablereactor3.scala
deleted file mode 100644
index 5810ed053f..0000000000
--- a/test/files/jvm/replyablereactor3.scala
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
-import scala.actors._
-import scala.actors.Actor._
-
-class MyActor extends ReplyReactor {
- def act() {
- try {
- loop {
- react {
- case 'hello =>
- sender ! 'hello
- case 'stop =>
- exit()
- }
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
-}
-
- def main(args: Array[String]) {
- val a = new MyActor
- a.start()
-
- val b = new Reactor[Any] {
- def act() {
- try {
- react {
- case r: MyActor =>
- var i = 0
- loop {
- i += 1
- val msg = r !? 'hello
- if (i % 10000 == 0)
- println(msg)
- if (i >= 50000) {
- r ! 'stop
- exit()
- }
- }
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
- }
- b.start()
-
- b ! a
- }
-}
diff --git a/test/files/jvm/replyablereactor4.check b/test/files/jvm/replyablereactor4.check
deleted file mode 100644
index cac0fffe3b..0000000000
--- a/test/files/jvm/replyablereactor4.check
+++ /dev/null
@@ -1,5 +0,0 @@
-Some('hello)
-Some('hello)
-Some('hello)
-Some('hello)
-Some('hello)
diff --git a/test/files/jvm/replyablereactor4.scala b/test/files/jvm/replyablereactor4.scala
deleted file mode 100644
index 95d63684dd..0000000000
--- a/test/files/jvm/replyablereactor4.scala
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
-import scala.actors._
-import scala.actors.Actor._
-
-class MyActor extends ReplyReactor {
- def act() {
- try {
- loop {
- react {
- case 'hello =>
- sender ! 'hello
- case 'stop =>
- exit()
- }
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
-}
-
- def main(args: Array[String]) {
- val a = new MyActor
- a.start()
-
- val b = new Reactor[Any] {
- def act() {
- try {
- react {
- case r: MyActor =>
- var i = 0
- loop {
- i += 1
- val msg = r !? (500, 'hello)
- if (i % 200000 == 0)
- println(msg)
- if (i >= 1000000) {
- r ! 'stop
- exit()
- }
- }
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
- }
- b.start()
-
- b ! a
- }
-}
diff --git a/test/files/jvm/replyreactor-react-sender.check b/test/files/jvm/replyreactor-react-sender.check
deleted file mode 100644
index d86bac9de5..0000000000
--- a/test/files/jvm/replyreactor-react-sender.check
+++ /dev/null
@@ -1 +0,0 @@
-OK
diff --git a/test/files/jvm/replyreactor-react-sender.scala b/test/files/jvm/replyreactor-react-sender.scala
deleted file mode 100644
index fdcea09035..0000000000
--- a/test/files/jvm/replyreactor-react-sender.scala
+++ /dev/null
@@ -1,53 +0,0 @@
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
- import scala.actors.ReplyReactor
- import scala.actors.Actor._
-
- val NUM = 2000
-
- def main(args: Array[String]) {
- var b: ReplyReactor = null
-
- val a = new ReplyReactor {
- def act() {
- try {
- var i = 0
- loopWhile (i < NUM) {
- i += 1
- react {
- case 'hello if sender == this => b ! 'fail
- case 'hello if sender == b => // do nothing
- }
- } andThen {
- b ! 'ok
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
- }
- a.start()
-
- b = new ReplyReactor {
- def act() {
- try {
- for (_ <- 0 until NUM)
- a ! 'hello
- react {
- case 'fail => println("FAIL")
- case 'ok => println("OK")
- case other => println(other)
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
- }
- b.start()
- }
-
-}
diff --git a/test/files/jvm/replyreactor.check b/test/files/jvm/replyreactor.check
deleted file mode 100644
index 4b2fea867a..0000000000
--- a/test/files/jvm/replyreactor.check
+++ /dev/null
@@ -1 +0,0 @@
-'hello
diff --git a/test/files/jvm/replyreactor.scala b/test/files/jvm/replyreactor.scala
deleted file mode 100644
index 7512fb0eb2..0000000000
--- a/test/files/jvm/replyreactor.scala
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
- import scala.actors.ReplyReactor
- def main(args: Array[String]) {
- val a = new ReplyReactor {
- def act() {
- try {
- react {
- case 'hello =>
- sender ! 'hello
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
- }
- a.start()
-
- val b = new ReplyReactor {
- def act() {
- try {
- react {
- case r: ReplyReactor =>
- r ! 'hello
- react {
- case any =>
- println(any)
- }
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
- }
- b.start()
-
- b ! a
- }
-}
diff --git a/test/files/jvm/scala-concurrent-tck.check b/test/files/jvm/scala-concurrent-tck.check
new file mode 100644
index 0000000000..bbe73c9982
--- /dev/null
+++ b/test/files/jvm/scala-concurrent-tck.check
@@ -0,0 +1 @@
+warning: there were 74 deprecation warnings; re-run with -deprecation for details
diff --git a/test/files/jvm/scala-concurrent-tck.scala b/test/files/jvm/scala-concurrent-tck.scala
index ce86d4aef0..ba405e97bd 100644
--- a/test/files/jvm/scala-concurrent-tck.scala
+++ b/test/files/jvm/scala-concurrent-tck.scala
@@ -165,6 +165,100 @@ def testTransformFailure(): Unit = once {
g onFailure { case e => done(e eq transformed) }
}
+ def testTransformResultToResult(): Unit = once {
+ done =>
+ Future("foo").transform {
+ case Success(s) => Success(s.toUpperCase)
+ case Failure(f) => throw new Exception("test failed")
+ } onComplete {
+ case Success("FOO") => done(true)
+ case _ => done(false)
+ }
+ }
+
+ def testTransformResultToFailure(): Unit = once {
+ done =>
+ val e = new Exception("expected")
+ Future("foo").transform {
+ case Success(s) => Failure(e)
+ case Failure(f) => throw new Exception("test failed")
+ } onComplete {
+ case Failure(`e`) => done(true)
+ case _ => done(false)
+ }
+ }
+
+ def testTransformFailureToResult(): Unit = once {
+ done =>
+ val e = "foo"
+ Future(throw new Exception("initial")).transform {
+ case Success(s) => throw new Exception("test failed")
+ case Failure(f) => Success(e)
+ } onComplete {
+ case Success(`e`) => done(true)
+ case _ => done(false)
+ }
+ }
+
+ def testTransformFailureToFailure(): Unit = once {
+ done =>
+ val e = new Exception("expected")
+ Future(throw new Exception("initial")).transform {
+ case Success(s) => throw new Exception("test failed")
+ case Failure(f) => Failure(e)
+ } onComplete {
+ case Failure(`e`) => done(true)
+ case _ => done(false)
+ }
+ }
+
+ def testTransformWithResultToResult(): Unit = once {
+ done =>
+ Future("foo").transformWith {
+ case Success(s) => Future(s.toUpperCase)
+ case Failure(f) => throw new Exception("test failed")
+ } onComplete {
+ case Success("FOO") => done(true)
+ case _ => done(false)
+ }
+ }
+
+ def testTransformWithResultToFailure(): Unit = once {
+ done =>
+ val e = new Exception("expected")
+ Future("foo").transformWith {
+ case Success(s) => Future(throw e)
+ case Failure(f) => throw new Exception("test failed")
+ } onComplete {
+ case Failure(`e`) => done(true)
+ case _ => done(false)
+ }
+ }
+
+ def testTransformWithFailureToResult(): Unit = once {
+ done =>
+ val e = "foo"
+ Future(throw new Exception("initial")).transformWith {
+ case Success(s) => throw new Exception("test failed")
+ case Failure(f) => Future(e)
+ } onComplete {
+ case Success(`e`) => done(true)
+ case _ => done(false)
+ }
+ }
+
+ def testTransformWithFailureToFailure(): Unit = once {
+ done =>
+ val e = new Exception("expected")
+ Future(throw new Exception("initial")).transformWith {
+ case Success(s) => throw new Exception("test failed")
+ case Failure(f) => Future(throw e)
+ } onComplete {
+ case Failure(`e`) => done(true)
+ case _ => done(false)
+ }
+ }
+
def testFoldFailure(): Unit = once {
done =>
val f = Future[Unit] { throw new Exception("expected") }
@@ -352,6 +446,14 @@ def testTransformFailure(): Unit = once {
h onFailure { case e => done(e eq cause) }
}
+ def testFallbackToThis(): Unit = {
+ def check(f: Future[Int]) = assert((f fallbackTo f) eq f)
+
+ check(Future { 1 })
+ check(Future.successful(1))
+ check(Future.failed[Int](new Exception))
+ }
+
testMapSuccess()
testMapFailure()
testFlatMapSuccess()
@@ -373,6 +475,16 @@ def testTransformFailure(): Unit = once {
testFallbackToFailure()
testTransformSuccess()
testTransformSuccessPF()
+ testTransformFailure()
+ testTransformFailurePF()
+ testTransformResultToResult()
+ testTransformResultToFailure()
+ testTransformFailureToResult()
+ testTransformFailureToFailure()
+ testTransformWithResultToResult()
+ testTransformWithResultToFailure()
+ testTransformWithFailureToResult()
+ testTransformWithFailureToFailure()
}
@@ -593,6 +705,17 @@ trait Exceptions extends TestBase {
}
+trait GlobalExecutionContext extends TestBase {
+ def testNameOfGlobalECThreads(): Unit = once {
+ done => Future({
+ val expectedName = "scala-execution-context-global-"+ Thread.currentThread.getId
+ done(expectedName == Thread.currentThread.getName)
+ })(ExecutionContext.global)
+ }
+
+ testNameOfGlobalECThreads()
+}
+
trait CustomExecutionContext extends TestBase {
import scala.concurrent.{ ExecutionContext, Awaitable }
@@ -772,6 +895,7 @@ with FutureProjections
with Promises
with BlockContexts
with Exceptions
+with GlobalExecutionContext
with CustomExecutionContext
with ExecutionContextPrepare
{
diff --git a/test/files/jvm/scheduler-adapter.check b/test/files/jvm/scheduler-adapter.check
deleted file mode 100644
index b278674cf0..0000000000
--- a/test/files/jvm/scheduler-adapter.check
+++ /dev/null
@@ -1,6 +0,0 @@
-before
-before
-before
-Two: received msg
-before
-One: received msg
diff --git a/test/files/jvm/scheduler-adapter.scala b/test/files/jvm/scheduler-adapter.scala
deleted file mode 100644
index 1c9cfe7019..0000000000
--- a/test/files/jvm/scheduler-adapter.scala
+++ /dev/null
@@ -1,54 +0,0 @@
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
-import scala.actors.{Actor, SchedulerAdapter}
-
-trait AdaptedActor extends Actor {
- override def scheduler =
- Test.adapted
-}
-
-object One extends AdaptedActor {
- def act() {
- try {
- Two.start()
- Two ! 'MsgForTwo
- react {
- case 'MsgForOne =>
- println("One: received msg")
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
-}
-
-object Two extends AdaptedActor {
- def act() {
- try {
- react {
- case 'MsgForTwo =>
- println("Two: received msg")
- One ! 'MsgForOne
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
-}
-
- val adapted =
- new SchedulerAdapter {
- def execute(block: => Unit) {
- println("before")
- block
- }
- }
-
- def main(args: Array[String]) {
- One.start()
- }
-}
diff --git a/test/files/jvm/t1449.check b/test/files/jvm/t1449.check
deleted file mode 100644
index d81cc0710e..0000000000
--- a/test/files/jvm/t1449.check
+++ /dev/null
@@ -1 +0,0 @@
-42
diff --git a/test/files/jvm/t1449.scala b/test/files/jvm/t1449.scala
deleted file mode 100644
index 7917d6f6d5..0000000000
--- a/test/files/jvm/t1449.scala
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
- import scala.actors.Actor._
- import scala.actors.Future
- import scala.actors.Futures._
- def main(args: Array[String]) {
- val a = actor {
- try {
- react {
- case ft: Future[a] =>
- println(ft())
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
- try {
- val ft = future { 42 }
- a ! ft
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
-}
diff --git a/test/files/jvm/t1948.scala b/test/files/jvm/t1948.scala
deleted file mode 100644
index 95777b8037..0000000000
--- a/test/files/jvm/t1948.scala
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
- import scala.actors._
- import scala.actors.Actor._
-
- def main (args: Array[String]) {
- val actors = (1 to 1000).toList map { x => actor {
- try {
- loop { react {
- case x: Array[Int] => reply ("OK"); exit }}
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- } }
- try {
- actors foreach { x => x !? new Array[Int] (1000000) }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
-
-}
diff --git a/test/files/jvm/t2359.check b/test/files/jvm/t2359.check
deleted file mode 100644
index 8a1218a102..0000000000
--- a/test/files/jvm/t2359.check
+++ /dev/null
@@ -1,5 +0,0 @@
-1
-2
-3
-4
-5
diff --git a/test/files/jvm/t2359.scala b/test/files/jvm/t2359.scala
deleted file mode 100644
index 76b78d44f7..0000000000
--- a/test/files/jvm/t2359.scala
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
- import scala.actors.Futures._
- def main(args: Array[String]) {
- val x = future {
- try {
- System.out.println(1)
- future {
- try {
- System.out.println(2)
- future {
- try {
- System.out.println(3)
- future {
- try {
- System.out.println(4)
- future {
- try {
- System.out.println(5)
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }()
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }()
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }()
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }()
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }()
- }
-}
diff --git a/test/files/jvm/t2530.check b/test/files/jvm/t2530.check
deleted file mode 100644
index 0f1c02158d..0000000000
--- a/test/files/jvm/t2530.check
+++ /dev/null
@@ -1,21 +0,0 @@
- Iteration 1 succeeded
- Iteration 2 succeeded
- Iteration 3 succeeded
- Iteration 4 succeeded
- Iteration 5 succeeded
- Iteration 6 succeeded
- Iteration 7 succeeded
- Iteration 8 succeeded
- Iteration 9 succeeded
- Iteration 10 succeeded
- Iteration 11 succeeded
- Iteration 12 succeeded
- Iteration 13 succeeded
- Iteration 14 succeeded
- Iteration 15 succeeded
- Iteration 16 succeeded
- Iteration 17 succeeded
- Iteration 18 succeeded
- Iteration 19 succeeded
- Iteration 20 succeeded
-Test done with no deadlock. Try again, it will not occur...
diff --git a/test/files/jvm/t2530.scala b/test/files/jvm/t2530.scala
deleted file mode 100644
index b41661e623..0000000000
--- a/test/files/jvm/t2530.scala
+++ /dev/null
@@ -1,98 +0,0 @@
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
- import scala.actors.{Future, Futures}
-
- def main(args:Array[String]) : Unit = {
- //scala.actors.Debug.level = 3
- val size = /*if (args.length > 0) Integer.parseInt(args(0)) else*/ 8
- val (m,n) = (size, size)
- def random = (for (i <- 0 until m*n) yield java.lang.Math.random).toArray
- val A = Matrix(m, n, random)
- val B = Matrix(m, n, random)
- val format = new java.text.DecimalFormat("000.00'ms'");
- var iter = 1
- val done = 21
- while (iter < done) {
- val start = System.nanoTime()
- val result = A * B
- val time = System.nanoTime() - start
- result match {
- case Some(result) => {
- printf(" Iteration %2d succeeded %n", iter/*, format.format(time / 1e6)*/)
- iter += 1
- }
- case None => {
- printf(">>>> Iteration %2d failed after %s <<<<< %n", iter, format.format(time / 1e6))
- iter = done
- }
- }
- }
- println("Test done with no deadlock. Try again, it will not occur...")
- }
-
-case class Matrix(numRows: Int, numCols: Int, values: Array[Double]) {
-
- def this(m:Int, n:Int) = this(m, n, new Array[Double](m*n))
-
- def offset(i:Int, j:Int) = i * numCols + j
- def apply(i:Int, j:Int) = values( offset(i,j) )
- def update(i:Int, j:Int, value:Double) = values(offset(i, j)) = value;
-
- def *(by:Matrix) = {
- val aM = numRows
- val aN = numCols
- assert(aM == by.numCols)
- assert(aN == by.numRows)
- val resultMatrix = new Matrix(aM, aM)
- val m = aM.asInstanceOf[Int]
- val n = aN.asInstanceOf[Int]
-
- val rows = for (j <- 0 until m) yield {
- Futures.future {
- try {
- val b_j = new Array[Double](n)
- var k = 0
- while (k < n) { // sadly, while loops are still faster than for loops
- b_j(k) = by(k,j)
- k += 1
- }
- var i = 0
- while (i < m) {
- var s = 0.0d;
- k = 0
- while (k < n) {
- s += Matrix.this(i,k) * b_j(k)
- k += 1
- }
- resultMatrix(i,j) = s
- i += 1
- }
- //printf("future %d of %d completed.%n", j, m)
- j
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
- }
-
- // rows.foreach { x=> x() } // This appears to force sequential execution, so use:
- // timeout is 10 years; see http://lampsvn.epfl.ch/trac/scala/ticket/2515
- val done: List[Option[Any]] = try {
- Futures.awaitAll(10*365*24*60*60*1000, rows.toArray : _*) // list to array, as varargs.
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- List()
- }
-
- if (done.contains(None))
- None
- else
- Some(resultMatrix)
- }
-
-}
-}
diff --git a/test/files/jvm/t3102.check b/test/files/jvm/t3102.check
deleted file mode 100644
index d705e0b20e..0000000000
--- a/test/files/jvm/t3102.check
+++ /dev/null
@@ -1,2 +0,0 @@
-42
-OK
diff --git a/test/files/jvm/t3102.scala b/test/files/jvm/t3102.scala
deleted file mode 100644
index d0e0704859..0000000000
--- a/test/files/jvm/t3102.scala
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
- import scala.actors.{Actor, TIMEOUT}
- import Actor._
-
- def main(args: Array[String]) {
- val a = actor {
- try {
- react {
- case 'hello =>
- reply(42)
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
-
- val b = actor {
- try {
- self.trapExit = true
- val ft = a !! 'hello
- println(ft())
- // no message should be left over in mailbox
- reactWithin(0) {
- case TIMEOUT =>
- println("OK")
- case any =>
- println(any)
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
- }
-}
diff --git a/test/files/jvm/t3356.check b/test/files/jvm/t3356.check
deleted file mode 100644
index 25f47b70c9..0000000000
--- a/test/files/jvm/t3356.check
+++ /dev/null
@@ -1,3 +0,0 @@
-sending download requests
-Couldn't download image because of java.lang.Exception: no connection
-Couldn't download image because of java.lang.Exception: no connection
diff --git a/test/files/jvm/t3356.scala b/test/files/jvm/t3356.scala
deleted file mode 100644
index 53bfd737cd..0000000000
--- a/test/files/jvm/t3356.scala
+++ /dev/null
@@ -1,58 +0,0 @@
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
-import scala.actors.{Actor, Exit, !, UncaughtException}
-import Actor._
-
-case class ImageInfo(text: String) {
- def downloadImage(): ImageData = {
- ImageData(text)
- }
-}
-
-case class ImageData(text: String)
-case class Download(info: ImageInfo)
-
-
- def scanForImageInfo(url: String): List[ImageInfo] =
- List(ImageInfo("A"), ImageInfo("B"))
-
- def renderImage(data: ImageData) {
- println("rendering image "+data.text)
- }
-
- def renderImages(url: String) {
- val imageInfos = scanForImageInfo(url)
- println("sending download requests")
- val dataFutures = for (info <- imageInfos) yield {
- val loader = link {
- react { case Download(info) =>
- throw new Exception("no connection")
- reply(info.downloadImage())
- }; {}
- }
- loader !! Download(info)
- }
- var i = 0
- loopWhile (i < imageInfos.size) {
- i += 1
- val FutureInput = dataFutures(i-1).inputChannel
- react {
- case FutureInput ! (data @ ImageData(_)) =>
- renderImage(data)
- case Exit(from, UncaughtException(_, Some(Download(info)), _, _, cause)) =>
- println("Couldn't download image because of "+cause)
- }
- }
- println("OK, all images rendered.")
- }
-
- def main(args: Array[String]) {
- actor {
- self.trapExit = true
- renderImages("panorama.epfl.ch")
- }
- }
-
-}
diff --git a/test/files/jvm/t3365.check b/test/files/jvm/t3365.check
deleted file mode 100644
index 0944b17279..0000000000
--- a/test/files/jvm/t3365.check
+++ /dev/null
@@ -1,5 +0,0 @@
-'hello
-'hello
-'hello
-'hello
-'hello
diff --git a/test/files/jvm/t3365.scala b/test/files/jvm/t3365.scala
deleted file mode 100644
index 8321428093..0000000000
--- a/test/files/jvm/t3365.scala
+++ /dev/null
@@ -1,68 +0,0 @@
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
-import scala.actors.{ReplyReactor, Channel, Actor, Future}
-
-case class ChannelMsg(chan: Channel[Any])
-
-class MyActor extends Actor {
- def act() {
- try {
- val chan = new Channel[Any](this)
- loop {
- react {
- case other: ReplyReactor =>
- other ! ChannelMsg(chan)
- loop {
- chan.react {
- case 'hello =>
- reply('hello)
- case 'stop =>
- exit()
- }
- }
- }
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
-}
-
- def main(args: Array[String]) {
- val a = new MyActor
- a.start()
-
- val b = new Actor {
- def act() {
- try {
- react {
- case ChannelMsg(c) =>
- var i = 0
- loop {
- i += 1
- val ft: Future[Any] = c !! 'hello
- ft.inputChannel.react {
- case msg =>
- if (i % 10000 == 0)
- println(msg)
- if (i >= 50000) {
- c ! 'stop
- exit()
- }
- }
- }
- }
- } catch {
- case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
- e.printStackTrace()
- }
- }
- }
- b.start()
-
- a ! b
- }
-}
diff --git a/test/files/jvm/t3407.check b/test/files/jvm/t3407.check
deleted file mode 100644
index a133c88bbe..0000000000
--- a/test/files/jvm/t3407.check
+++ /dev/null
@@ -1,10 +0,0 @@
-result: 42
-result: 42
-result: 42
-result: 42
-result: 42
-result: 42
-result: 42
-result: 42
-result: 42
-result: 42
diff --git a/test/files/jvm/t3407.scala b/test/files/jvm/t3407.scala
deleted file mode 100644
index 757fa3a438..0000000000
--- a/test/files/jvm/t3407.scala
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
- import scala.actors._, scala.actors.Actor._
-
- def main(args: Array[String]) {
- for (i <- 1 to 10) {
- val ft = Futures.future { 42 }
- println("result: " + ft())
- }
-
- for (i <- 1 to 10) {
- receiveWithin(0) {
- case TIMEOUT =>
- case msg => println("unexpected: " + msg)
- }
- }
- }
-
-}
diff --git a/test/files/jvm/t3412-channel.check b/test/files/jvm/t3412-channel.check
deleted file mode 100644
index 954c6e835d..0000000000
--- a/test/files/jvm/t3412-channel.check
+++ /dev/null
@@ -1,10 +0,0 @@
-6
-6
-6
-6
-6
-6
-6
-6
-6
-6
diff --git a/test/files/jvm/t3412-channel.scala b/test/files/jvm/t3412-channel.scala
deleted file mode 100644
index af319d2303..0000000000
--- a/test/files/jvm/t3412-channel.scala
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
- import scala.actors._, scala.actors.Actor._, scala.actors.Futures._
-
- def main(args: Array[String]) {
-
- actor {
- val C: Channel[Int] = new Channel[Int](self)
-
- def respondAll(fts: List[Future[Int]], cnt: Int): Unit =
- fts match {
- case List() => C ! 0
- case ft :: rest =>
- if (cnt % 100 == 0)
- println(ft())
- respondAll(rest, cnt + 1)
- }
-
- actor {
- val fts = for (_ <- 1 to 1000)
- yield C !! (3, {case x: Int => x})
-
- actor {
- respondAll(fts.toList, 0)
- }
- }
-
- loop {
- C.react {
- case 0 => exit()
- case i => reply(i * 2)
- }
- }
- }
-
- }
-
-}
diff --git a/test/files/jvm/t3412.check b/test/files/jvm/t3412.check
deleted file mode 100644
index 954c6e835d..0000000000
--- a/test/files/jvm/t3412.check
+++ /dev/null
@@ -1,10 +0,0 @@
-6
-6
-6
-6
-6
-6
-6
-6
-6
-6
diff --git a/test/files/jvm/t3412.scala b/test/files/jvm/t3412.scala
deleted file mode 100644
index fde6c04cb7..0000000000
--- a/test/files/jvm/t3412.scala
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
- import scala.actors._, scala.actors.Actor._, scala.actors.Futures._
-
- def main(args: Array[String]) {
-
- val a = actor {
- loop { react {
- case i: Int => reply(i * 2)
- case 'stop => exit()
- } }
- }
-
- val fts = for (_ <- 1 to 1000)
- yield a !! (3, {case x: Int => x})
-
- def respondAll(fts: List[Future[Int]], cnt: Int): Unit =
- fts match {
- case List() => a ! 'stop
- case ft :: rest =>
- if (cnt % 100 == 0)
- println(ft())
- respondAll(rest, cnt + 1)
- }
-
- actor {
- respondAll(fts.toList, 0)
- }
-
- }
-
-}
diff --git a/test/files/jvm/t3470.check b/test/files/jvm/t3470.check
deleted file mode 100644
index 94cb526756..0000000000
--- a/test/files/jvm/t3470.check
+++ /dev/null
@@ -1,3 +0,0 @@
-A: started: 1
-A: started: 2
-A: started: 3
diff --git a/test/files/jvm/t3470.scala b/test/files/jvm/t3470.scala
deleted file mode 100644
index bcb1d4f8de..0000000000
--- a/test/files/jvm/t3470.scala
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
- import scala.actors._
-
- def expectActorState(a: Reactor[T] forSome { type T }, s: Actor.State.Value) {
- var done = false
- var i = 0
- while (!done) {
- i = i + 1
- if (i == 10) { // only wait for 2 seconds total
- println("FAIL ["+a+": expected "+s+"]")
- done = true
- }
-
- Thread.sleep(200)
- if (a.getState == s) // success
- done = true
- }
- }
-
- def main(args: Array[String]) {
- val a = new Actor { var c = 0; def act() = { c += 1; println("A: started: " + c) } }
- a.start()
- expectActorState(a, Actor.State.Terminated)
- a.restart()
- expectActorState(a, Actor.State.Terminated)
- a.restart()
- }
-
-}
diff --git a/test/files/jvm/t3838.check b/test/files/jvm/t3838.check
deleted file mode 100644
index 154227a350..0000000000
--- a/test/files/jvm/t3838.check
+++ /dev/null
@@ -1 +0,0 @@
-caught java.lang.RuntimeException: unhandled timeout
diff --git a/test/files/jvm/t3838.scala b/test/files/jvm/t3838.scala
deleted file mode 100644
index a1a71d1049..0000000000
--- a/test/files/jvm/t3838.scala
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-@deprecated("Suppress warnings", since="2.11")
-object Test {
- import scala.actors.Actor._
- def main(args: Array[String]) {
- actor {
- try {
- receiveWithin(1) {
- case str: String => println(str)
- }
- } catch {
- case e: Exception => println("caught "+e)
- }
- }
- }
-}
diff --git a/test/files/jvm/t7146.scala b/test/files/jvm/t7146.scala
index aaa3dc7ca4..ea734472d5 100644
--- a/test/files/jvm/t7146.scala
+++ b/test/files/jvm/t7146.scala
@@ -10,7 +10,7 @@ object Test {
ExecutionContext.global.toString.startsWith("scala.concurrent.impl.ExecutionContextImpl"))
val i = ExecutionContext.global.asInstanceOf[{ def executor: Executor }]
println("should be scala.concurrent.forkjoin.ForkJoinPool == " +
- i.executor.toString.startsWith("scala.concurrent.forkjoin.ForkJoinPool"))
+ (i.executor.getClass.getSuperclass.getName == "scala.concurrent.forkjoin.ForkJoinPool"))
val u = i.executor.
asInstanceOf[{ def getUncaughtExceptionHandler: Thread.UncaughtExceptionHandler }].
getUncaughtExceptionHandler
diff --git a/test/files/jvm/t8582.check b/test/files/jvm/t8582.check
index e388366270..0e4da90398 100644
--- a/test/files/jvm/t8582.check
+++ b/test/files/jvm/t8582.check
@@ -1,3 +1,6 @@
+t8582.scala:17: warning: class BeanInfo in package beans is deprecated: the generation of BeanInfo classes is no longer supported
+ class C1
+ ^
getClass on module gives module class
class p1.p2.Singleton$Singleton$
diff --git a/test/files/jvm/t8582.flags b/test/files/jvm/t8582.flags
new file mode 100644
index 0000000000..dcc59ebe32
--- /dev/null
+++ b/test/files/jvm/t8582.flags
@@ -0,0 +1 @@
+-deprecation
diff --git a/test/files/jvm/try-type-tests.scala b/test/files/jvm/try-type-tests.scala
index 962afbd30f..b3926020f0 100644
--- a/test/files/jvm/try-type-tests.scala
+++ b/test/files/jvm/try-type-tests.scala
@@ -118,6 +118,44 @@ trait TryStandard {
assert(f.transform(succ, fail).get == 0)
}
+ def testSuccessEither(): Unit = {
+ val t = Success(1)
+ assert(t.toEither.isRight)
+ }
+
+ def testFailureEither(): Unit = {
+ val t = Failure(new Exception("foo"))
+ assert(t.toEither.isLeft)
+ }
+
+ def testFoldSuccess(): Unit = {
+ val t = Success(1)
+ val res = t.fold("Throws " + _, "Returns " + _)
+ assert(res == "Returns 1")
+ }
+
+ def testFoldFailure(): Unit = {
+ val t = Failure(new Exception("foo"))
+ val res = t.fold("Throws " + _, "Returns " + _)
+ assert(res == "Throws java.lang.Exception: foo")
+ }
+
+ def testFoldSuccessFailure(): Unit = {
+ val t = Success(1)
+ val res = t.fold("Throws " + _, _ => throw new Exception("foo"))
+ assert(res == "Throws java.lang.Exception: foo")
+ }
+
+ def testFoldFailureFailure(): Unit = {
+ val t = Failure(new Exception("foo"))
+ val res = try {
+ t.fold(_ => throw new Exception("bar"), "Returns " + _)
+ } catch {
+ case e: Throwable => "Throws " + e
+ }
+ assert(res == "Throws java.lang.Exception: bar")
+ }
+
testForeachSuccess()
testForeachFailure()
testFlatMapSuccess()
@@ -136,6 +174,11 @@ trait TryStandard {
testFailedFailure()
testSuccessTransform()
testFailureTransform()
+ testSuccessEither()
+ testFailureEither()
+ testFoldSuccess()
+ testFoldFailure()
+ testFoldSuccessFailure()
}
object Test
diff --git a/test/files/neg/beanInfoDeprecation.check b/test/files/neg/beanInfoDeprecation.check
new file mode 100644
index 0000000000..788b277818
--- /dev/null
+++ b/test/files/neg/beanInfoDeprecation.check
@@ -0,0 +1,6 @@
+beanInfoDeprecation.scala:2: warning: class BeanInfo in package beans is deprecated: the generation of BeanInfo classes is no longer supported
+class C
+ ^
+error: No warnings can be incurred under -Xfatal-warnings.
+one warning found
+one error found
diff --git a/test/files/neg/beanInfoDeprecation.flags b/test/files/neg/beanInfoDeprecation.flags
new file mode 100644
index 0000000000..c6bfaf1f64
--- /dev/null
+++ b/test/files/neg/beanInfoDeprecation.flags
@@ -0,0 +1 @@
+-deprecation -Xfatal-warnings
diff --git a/test/files/neg/beanInfoDeprecation.scala b/test/files/neg/beanInfoDeprecation.scala
new file mode 100644
index 0000000000..c7e3a86202
--- /dev/null
+++ b/test/files/neg/beanInfoDeprecation.scala
@@ -0,0 +1,2 @@
+@scala.beans.BeanInfo
+class C
diff --git a/test/files/neg/deprecated-target.check b/test/files/neg/deprecated-target.check
new file mode 100644
index 0000000000..307d3d25ab
--- /dev/null
+++ b/test/files/neg/deprecated-target.check
@@ -0,0 +1,4 @@
+warning: -target is deprecated: -target:jvm-1.7 is deprecated, forcing use of jvm-1.8
+error: No warnings can be incurred under -Xfatal-warnings.
+one warning found
+one error found
diff --git a/test/files/neg/deprecated-target.flags b/test/files/neg/deprecated-target.flags
new file mode 100644
index 0000000000..458ded8123
--- /dev/null
+++ b/test/files/neg/deprecated-target.flags
@@ -0,0 +1 @@
+-target:jvm-1.7 -deprecation -Xfatal-warnings
diff --git a/test/files/neg/deprecated-target.scala b/test/files/neg/deprecated-target.scala
new file mode 100644
index 0000000000..9dccdd5e59
--- /dev/null
+++ b/test/files/neg/deprecated-target.scala
@@ -0,0 +1 @@
+class C \ No newline at end of file
diff --git a/test/files/neg/logImplicits.check b/test/files/neg/logImplicits.check
index 270882b71a..df7b359767 100644
--- a/test/files/neg/logImplicits.check
+++ b/test/files/neg/logImplicits.check
@@ -1,10 +1,10 @@
-logImplicits.scala:2: applied implicit conversion from xs.type to ?{def size: ?} = implicit def byteArrayOps(xs: Array[Byte]): scala.collection.mutable.ArrayOps[Byte]
+logImplicits.scala:2: applied implicit conversion from xs.type to ?{def size: ?} = implicit def _byteArrayOps(xs: Array[Byte]): scala.collection.mutable.ArrayOps.ofByte
def f(xs: Array[Byte]) = xs.size
^
logImplicits.scala:7: applied implicit conversion from String("abc") to ?{def map: ?} = implicit def augmentString(x: String): scala.collection.immutable.StringOps
def f = "abc" map (_ + 1)
^
-logImplicits.scala:15: inferred view from String("abc") to Int = C.this.convert:(p: String("abc"))Int
+logImplicits.scala:15: inferred view from String("abc") to Int = C.this.convert:(p: String)Int
math.max(122, x: Int)
^
logImplicits.scala:19: applied implicit conversion from Int(1) to ?{def ->: ?} = implicit def ArrowAssoc[A](self: A): ArrowAssoc[A]
diff --git a/test/files/neg/names-defaults-neg.check b/test/files/neg/names-defaults-neg.check
index a43bf66811..8a6aafd67a 100644
--- a/test/files/neg/names-defaults-neg.check
+++ b/test/files/neg/names-defaults-neg.check
@@ -118,68 +118,74 @@ names-defaults-neg.scala:93: warning: the parameter name y has been deprecated.
names-defaults-neg.scala:93: error: parameter 'b' is already specified at parameter position 1
deprNam3(y = 10, b = 2)
^
-names-defaults-neg.scala:98: error: unknown parameter name: m
+names-defaults-neg.scala:96: warning: naming parameter deprNam4Arg has been deprecated.
+ deprNam4(deprNam4Arg = null)
+ ^
+names-defaults-neg.scala:98: warning: naming parameter deprNam5Arg has been deprecated.
+ deprNam5(deprNam5Arg = null)
+ ^
+names-defaults-neg.scala:102: error: unknown parameter name: m
f3818(y = 1, m = 1)
^
-names-defaults-neg.scala:131: error: reference to var2 is ambiguous; it is both a method parameter and a variable in scope.
+names-defaults-neg.scala:135: error: reference to var2 is ambiguous; it is both a method parameter and a variable in scope.
delay(var2 = 40)
^
-names-defaults-neg.scala:134: error: missing parameter type for expanded function ((x$1) => a = x$1)
+names-defaults-neg.scala:138: error: missing parameter type for expanded function ((x$1) => a = x$1)
val taf2: Int => Unit = testAnnFun(a = _, b = get("+"))
^
-names-defaults-neg.scala:134: error: not found: value a
+names-defaults-neg.scala:138: error: not found: value a
val taf2: Int => Unit = testAnnFun(a = _, b = get("+"))
^
-names-defaults-neg.scala:134: error: not found: value get
+names-defaults-neg.scala:138: error: not found: value get
val taf2: Int => Unit = testAnnFun(a = _, b = get("+"))
^
-names-defaults-neg.scala:135: error: parameter 'a' is already specified at parameter position 1
+names-defaults-neg.scala:139: error: parameter 'a' is already specified at parameter position 1
val taf3 = testAnnFun(b = _: String, a = get(8))
^
-names-defaults-neg.scala:136: error: missing parameter type for expanded function ((x$3) => testAnnFun(x$3, ((x$4) => b = x$4)))
+names-defaults-neg.scala:140: error: missing parameter type for expanded function ((x$3) => testAnnFun(x$3, ((x$4) => b = x$4)))
val taf4: (Int, String) => Unit = testAnnFun(_, b = _)
^
-names-defaults-neg.scala:136: error: missing parameter type for expanded function ((x$4) => b = x$4)
+names-defaults-neg.scala:140: error: missing parameter type for expanded function ((x$4) => b = x$4)
val taf4: (Int, String) => Unit = testAnnFun(_, b = _)
^
-names-defaults-neg.scala:136: error: not found: value b
+names-defaults-neg.scala:140: error: not found: value b
val taf4: (Int, String) => Unit = testAnnFun(_, b = _)
^
-names-defaults-neg.scala:144: error: variable definition needs type because 'x' is used as a named argument in its body.
+names-defaults-neg.scala:148: error: variable definition needs type because 'x' is used as a named argument in its body.
def t3 { var x = t.f(x = 1) }
^
-names-defaults-neg.scala:147: error: variable definition needs type because 'x' is used as a named argument in its body.
+names-defaults-neg.scala:151: error: variable definition needs type because 'x' is used as a named argument in its body.
object t6 { var x = t.f(x = 1) }
^
-names-defaults-neg.scala:147: warning: failed to determine if 'x = ...' is a named argument or an assignment expression.
+names-defaults-neg.scala:151: warning: failed to determine if 'x = ...' is a named argument or an assignment expression.
an explicit type is required for the definition mentioned in the error message above.
object t6 { var x = t.f(x = 1) }
^
-names-defaults-neg.scala:150: error: variable definition needs type because 'x' is used as a named argument in its body.
+names-defaults-neg.scala:154: error: variable definition needs type because 'x' is used as a named argument in its body.
class t9 { var x = t.f(x = 1) }
^
-names-defaults-neg.scala:150: warning: failed to determine if 'x = ...' is a named argument or an assignment expression.
+names-defaults-neg.scala:154: warning: failed to determine if 'x = ...' is a named argument or an assignment expression.
an explicit type is required for the definition mentioned in the error message above.
class t9 { var x = t.f(x = 1) }
^
-names-defaults-neg.scala:164: error: variable definition needs type because 'x' is used as a named argument in its body.
+names-defaults-neg.scala:168: error: variable definition needs type because 'x' is used as a named argument in its body.
def u3 { var x = u.f(x = 1) }
^
-names-defaults-neg.scala:167: error: variable definition needs type because 'x' is used as a named argument in its body.
+names-defaults-neg.scala:171: error: variable definition needs type because 'x' is used as a named argument in its body.
def u6 { var x = u.f(x = "32") }
^
-names-defaults-neg.scala:170: error: reference to x is ambiguous; it is both a method parameter and a variable in scope.
+names-defaults-neg.scala:174: error: reference to x is ambiguous; it is both a method parameter and a variable in scope.
def u9 { var x: Int = u.f(x = 1) }
^
-names-defaults-neg.scala:177: error: variable definition needs type because 'x' is used as a named argument in its body.
+names-defaults-neg.scala:181: error: variable definition needs type because 'x' is used as a named argument in its body.
class u15 { var x = u.f(x = 1) }
^
-names-defaults-neg.scala:177: warning: failed to determine if 'x = ...' is a named argument or an assignment expression.
+names-defaults-neg.scala:181: warning: failed to determine if 'x = ...' is a named argument or an assignment expression.
an explicit type is required for the definition mentioned in the error message above.
class u15 { var x = u.f(x = 1) }
^
-names-defaults-neg.scala:180: error: reference to x is ambiguous; it is both a method parameter and a variable in scope.
+names-defaults-neg.scala:184: error: reference to x is ambiguous; it is both a method parameter and a variable in scope.
class u18 { var x: Int = u.f(x = 1) }
^
-four warnings found
+6 warnings found
46 errors found
diff --git a/test/files/neg/names-defaults-neg.scala b/test/files/neg/names-defaults-neg.scala
index a97b590bf2..b326d3b5bd 100644
--- a/test/files/neg/names-defaults-neg.scala
+++ b/test/files/neg/names-defaults-neg.scala
@@ -92,6 +92,10 @@ object Test extends App {
def deprNam3(@deprecatedName('x) a: Int, @deprecatedName('y) b: Int) = a + b
deprNam3(y = 10, b = 2)
+ def deprNam4(@deprecatedName('deprNam4Arg) deprNam4Arg: String) = 0
+ deprNam4(deprNam4Arg = null)
+ def deprNam5(@deprecatedName deprNam5Arg: String) = 0
+ deprNam5(deprNam5Arg = null)
// t3818
def f3818(x: Int = 1, y: Int, z: Int = 1) = 0
diff --git a/test/files/neg/t6289.check b/test/files/neg/t6289.check
index 989932750f..7b2b4b2d32 100644
--- a/test/files/neg/t6289.check
+++ b/test/files/neg/t6289.check
@@ -1,9 +1,3 @@
-#partest java6
-t6289/J.java:2: method does not override or implement a method from a supertype
- @Override public void foo() { }
- ^
-1 error
-#partest !java6
t6289/J.java:2: error: method does not override or implement a method from a supertype
@Override public void foo() { }
^
diff --git a/test/files/neg/t8764.check b/test/files/neg/t8764.check
deleted file mode 100644
index 6d89ebe106..0000000000
--- a/test/files/neg/t8764.check
+++ /dev/null
@@ -1,6 +0,0 @@
-t8764.scala:8: error: type mismatch;
- found : AnyVal
- required: Double
- val d: Double = a.productElement(0)
- ^
-one error found
diff --git a/test/files/neg/t8764.flags b/test/files/neg/t8764.flags
deleted file mode 100644
index 48fd867160..0000000000
--- a/test/files/neg/t8764.flags
+++ /dev/null
@@ -1 +0,0 @@
--Xexperimental
diff --git a/test/files/neg/t8764.scala b/test/files/neg/t8764.scala
deleted file mode 100644
index dc5bfb0160..0000000000
--- a/test/files/neg/t8764.scala
+++ /dev/null
@@ -1,9 +0,0 @@
-object Main {
-
- case class IntAndDouble(i: Int, d: Double)
-
- // a.productElement used to be Int => Double
- // now: Int => AnyVal
- val a = IntAndDouble(1, 5.0)
- val d: Double = a.productElement(0)
-}
diff --git a/test/files/neg/t8849.check b/test/files/neg/t8849.check
new file mode 100644
index 0000000000..15b00aee8b
--- /dev/null
+++ b/test/files/neg/t8849.check
@@ -0,0 +1,7 @@
+t8849.scala:8: error: ambiguous implicit values:
+ both value global in object Implicits of type => scala.concurrent.ExecutionContext
+ and value dummy of type scala.concurrent.ExecutionContext
+ match expected type scala.concurrent.ExecutionContext
+ require(implicitly[ExecutionContext] eq dummy)
+ ^
+one error found
diff --git a/test/files/neg/t8849.scala b/test/files/neg/t8849.scala
new file mode 100644
index 0000000000..336f16b40f
--- /dev/null
+++ b/test/files/neg/t8849.scala
@@ -0,0 +1,10 @@
+import scala.concurrent.ExecutionContext
+import ExecutionContext.Implicits.global
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ implicit val dummy: ExecutionContext = null
+ require(scala.concurrent.ExecutionContext.Implicits.global ne null)
+ require(implicitly[ExecutionContext] eq dummy)
+ }
+} \ No newline at end of file
diff --git a/test/files/pos/MailBox.scala b/test/files/pos/MailBox.scala
index 8e27bd362d..6bb25adb19 100644
--- a/test/files/pos/MailBox.scala
+++ b/test/files/pos/MailBox.scala
@@ -1,6 +1,6 @@
package test;
-import scala.actors.TIMEOUT;
+object TIMEOUT
class MailBox {
diff --git a/test/files/pos/alladin763.scala b/test/files/pos/alladin763.scala
new file mode 100644
index 0000000000..29c9b25318
--- /dev/null
+++ b/test/files/pos/alladin763.scala
@@ -0,0 +1,37 @@
+// Test from http://lrytz.github.io/scala-aladdin-bugtracker/displayItem.do%3Fid=763.html
+// and expanded with package object variants
+
+
+trait Foo { type T; def apply() : T }
+object e extends Foo { type T = Int; def apply() = 42 }
+
+package p {
+ trait T[X] { def O : { def apply(): X } }
+ object `package` extends T[Int] {
+ def O: { def apply(): Int } = new { def apply(): Int = 42 }
+ }
+
+ object Test {
+ val x: Int = O()
+ }
+}
+
+object Test {
+
+ val f = new Foo { type T = Int; def apply() = 42 }
+
+ def main(args: Array[String]): Unit = {
+ val g = new Foo { type T = Int; def apply() = 42 }
+
+ (e: Foo)()
+ val ee: Int = e()
+
+ (f: Foo)()
+ val ff: Int = f()
+
+ (g: Foo)()
+ val gg: Int = g()
+
+ val pp: Int = p.O()
+ }
+}
diff --git a/test/files/pos/functions.scala b/test/files/pos/functions.scala
index 0207523dde..25d1c46eac 100644
--- a/test/files/pos/functions.scala
+++ b/test/files/pos/functions.scala
@@ -1,4 +1,6 @@
-import scala.actors.Actor
+object Actor {
+ def receive[A](f: PartialFunction[Any, A]): A = ???
+}
object Test {
diff --git a/test/files/pos/t533.scala b/test/files/pos/t533.scala
deleted file mode 100644
index 0a6515fed3..0000000000
--- a/test/files/pos/t533.scala
+++ /dev/null
@@ -1,11 +0,0 @@
-import scala.actors._
-
-object test extends Actor {
- def act() {
- receive {
- case TIMEOUT => Console.println("TIMEOUT")
- //case _ => Console.println("_")
- }
- }
-}
-
diff --git a/test/files/pos/t6778.scala b/test/files/pos/t6778.scala
new file mode 100644
index 0000000000..b7483c8fce
--- /dev/null
+++ b/test/files/pos/t6778.scala
@@ -0,0 +1,5 @@
+object test extends AnyRef with App {
+ // Check that random can be called with parenthesis.
+ scala.math.random()
+}
+
diff --git a/test/files/pos/t7784.scala b/test/files/pos/t7784.scala
new file mode 100644
index 0000000000..e6824a4203
--- /dev/null
+++ b/test/files/pos/t7784.scala
@@ -0,0 +1,13 @@
+object Test {
+ final val a = ""
+ var b: a.type = a
+ b = a
+
+ final val x = classOf[Object]
+ var y: x.type = x
+ y = x
+
+ final val e = Thread.State.NEW
+ var e1: e.type = e
+ e1 = e
+}
diff --git a/test/files/pos/t8462.scala b/test/files/pos/t8462.scala
new file mode 100644
index 0000000000..6946cf8e5e
--- /dev/null
+++ b/test/files/pos/t8462.scala
@@ -0,0 +1,11 @@
+
+trait ConstantOps {
+ def exprs = (
+ 1 << 2L : Int, // was: error: type mismatch; found : Long(4L)
+ 64 >> 2L : Int, // was: error: type mismatch; found : Long(4L)
+ 64 >>> 2L : Int, // was: error: type mismatch; found : Long(4L)
+ 'a' << 2L : Int,
+ 'a' >> 2L : Int,
+ 'a'>>> 2L : Int
+ )
+}
diff --git a/test/files/pos/t8862a.scala b/test/files/pos/t8862a.scala
new file mode 100644
index 0000000000..f9576707ba
--- /dev/null
+++ b/test/files/pos/t8862a.scala
@@ -0,0 +1,47 @@
+package p {
+
+ abstract class C[A] {
+ def x: A
+ implicit def oops: A = x
+ implicit def oopso: Option[A] = None
+ }
+
+ package q {
+
+ class Oops
+
+ object `package` extends C[Oops] {
+ override def x = new Oops
+ }
+
+ object Blah {
+ oops
+ oopso
+
+ // implicits found in enclosing context
+ implicitly[Oops]
+ implicitly[Option[Oops]]
+ }
+ }
+}
+
+package other {
+
+ object Blah {
+ // implicits found through this import
+ import p.q._
+
+ oops
+ oopso
+
+ implicitly[Oops]
+ implicitly[Option[Oops]]
+ }
+
+
+ object Blee {
+ // implicits found through the companion implicits
+ implicitly[p.q.Oops]
+ implicitly[Option[p.q.Oops]]
+ }
+}
diff --git a/test/files/pos/t8862b.scala b/test/files/pos/t8862b.scala
new file mode 100644
index 0000000000..8be7fb5fab
--- /dev/null
+++ b/test/files/pos/t8862b.scala
@@ -0,0 +1,12 @@
+package p {
+ trait T[X] { def O : { def apply(): X } }
+ object `package` extends T[Int] {
+ def O: { def apply(): Int } = new { def apply(): Int = 42 }
+ }
+
+ object Test {
+ def main(args: Array[String]): Unit = {
+ val x: Int = O()
+ }
+ }
+}
diff --git a/test/files/pos/t9074.scala b/test/files/pos/t9074.scala
new file mode 100644
index 0000000000..67db281f54
--- /dev/null
+++ b/test/files/pos/t9074.scala
@@ -0,0 +1,24 @@
+package blam {
+
+ package foo {
+
+ trait F[T] {
+ def f(d: Double, t: T): T = ???
+ def f(d: Int, t: T): T = ???
+ def f(d: String, t: T): T = ???
+
+ def g[A](a: T): T = ???
+ def g(a: Int) = ???
+ }
+ }
+
+ package object foo extends foo.F[Double] {
+ override def f(d: Double, t: Double): Double = ???
+ }
+}
+
+object Test {
+ import blam._
+ foo.f("3", 4.0)
+ foo.g[Any](1d) : Double
+}
diff --git a/test/files/pos/t9074b.scala b/test/files/pos/t9074b.scala
new file mode 100644
index 0000000000..dadcebf399
--- /dev/null
+++ b/test/files/pos/t9074b.scala
@@ -0,0 +1,15 @@
+trait Echo [T] {
+ def echo(t: T): Unit
+}
+
+trait IntEcho extends Echo[Int] {
+ def echo(t: Int) = println(t)
+}
+
+object echo extends IntEcho
+package object echo1 extends IntEcho
+
+object App extends App {
+ echo.echo(1)
+ echo1.echo(1)
+}
diff --git a/test/files/pos/t9131.scala b/test/files/pos/t9131.scala
new file mode 100644
index 0000000000..1a186a0a24
--- /dev/null
+++ b/test/files/pos/t9131.scala
@@ -0,0 +1,12 @@
+class Test {
+
+ def byNameFunc(f: (=> (() => Any)) => Any): Unit = ()
+
+ def test = {
+ // "value apply is not a member of => () => Any"
+ byNameFunc(z => z())
+ // okay
+ byNameFunc(z => z.apply())
+ byNameFunc(z => {val f = z; f()})
+ }
+}
diff --git a/test/files/pos/t9326a.scala b/test/files/pos/t9326a.scala
new file mode 100644
index 0000000000..aefc735585
--- /dev/null
+++ b/test/files/pos/t9326a.scala
@@ -0,0 +1,6 @@
+package p
+
+trait M[A]
+
+class C extends M[Tuple1[X] forSome { type X }]
+
diff --git a/test/files/run/analyzerPlugins.check b/test/files/run/analyzerPlugins.check
index 9803465ddc..1bb7c6ceab 100644
--- a/test/files/run/analyzerPlugins.check
+++ b/test/files/run/analyzerPlugins.check
@@ -19,7 +19,7 @@ canAdaptAnnotations(Trees$Typed, Any) [1]
canAdaptAnnotations(Trees$Typed, Int) [1]
lub(List(Int @testAnn, Int)) [1]
pluginsPt(?, Trees$Annotated) [7]
-pluginsPt(?, Trees$Apply) [8]
+pluginsPt(?, Trees$Apply) [11]
pluginsPt(?, Trees$ApplyImplicitView) [2]
pluginsPt(?, Trees$Assign) [7]
pluginsPt(?, Trees$Block) [4]
@@ -31,7 +31,7 @@ pluginsPt(?, Trees$Literal) [16]
pluginsPt(?, Trees$New) [5]
pluginsPt(?, Trees$PackageDef) [1]
pluginsPt(?, Trees$Return) [1]
-pluginsPt(?, Trees$Select) [47]
+pluginsPt(?, Trees$Select) [50]
pluginsPt(?, Trees$Super) [2]
pluginsPt(?, Trees$This) [20]
pluginsPt(?, Trees$TypeApply) [3]
@@ -93,6 +93,7 @@ pluginsTypeSigAccessor(value x) [1]
pluginsTypeSigAccessor(value y) [1]
pluginsTypeSigAccessor(variable count) [2]
pluginsTyped( <: Int, Trees$TypeBoundsTree) [2]
+pluginsTyped(()Double, Trees$Select) [6]
pluginsTyped(()Object, Trees$Select) [1]
pluginsTyped(()String, Trees$Ident) [1]
pluginsTyped(()String, Trees$TypeApply) [1]
@@ -112,7 +113,7 @@ pluginsTyped(<notype>, Trees$PackageDef) [1]
pluginsTyped(<notype>, Trees$TypeDef) [1]
pluginsTyped(<notype>, Trees$ValDef) [21]
pluginsTyped(=> Boolean @testAnn, Trees$Select) [1]
-pluginsTyped(=> Double, Trees$Select) [4]
+pluginsTyped(=> Double, Trees$Select) [1]
pluginsTyped(=> Int, Trees$Select) [5]
pluginsTyped(=> Int, Trees$TypeApply) [1]
pluginsTyped(=> String @testAnn, Trees$Select) [1]
@@ -131,6 +132,7 @@ pluginsTyped(Boolean(false), Trees$Literal) [2]
pluginsTyped(Boolean, Trees$Apply) [1]
pluginsTyped(Boolean, Trees$Select) [4]
pluginsTyped(Char('c'), Trees$Literal) [2]
+pluginsTyped(Double, Trees$Apply) [3]
pluginsTyped(Double, Trees$Select) [6]
pluginsTyped(Int @testAnn, Trees$TypeTree) [2]
pluginsTyped(Int @testAnn, Trees$Typed) [2]
diff --git a/test/files/run/classfile-format-51.scala b/test/files/run/classfile-format-51.scala
index 7523130afa..da322bb5d9 100644
--- a/test/files/run/classfile-format-51.scala
+++ b/test/files/run/classfile-format-51.scala
@@ -1,6 +1,5 @@
import java.io.{File, FileOutputStream}
-import scala.tools.nsc.settings.ScalaVersion
import scala.tools.partest._
import scala.tools.asm
import asm.{AnnotationVisitor, ClassWriter, FieldVisitor, Handle, MethodVisitor, Opcodes}
diff --git a/test/files/run/classfile-format-52.scala b/test/files/run/classfile-format-52.scala
index 453f61ac84..e278d40b8b 100644
--- a/test/files/run/classfile-format-52.scala
+++ b/test/files/run/classfile-format-52.scala
@@ -1,6 +1,5 @@
import java.io.{File, FileOutputStream}
-import scala.tools.nsc.settings.ScalaVersion
import scala.tools.partest._
import scala.tools.asm
import asm.{AnnotationVisitor, ClassWriter, FieldVisitor, Handle, MethodVisitor, Opcodes}
diff --git a/test/files/run/concurrent-stream.check b/test/files/run/concurrent-stream.check
deleted file mode 100644
index d4adf84490..0000000000
--- a/test/files/run/concurrent-stream.check
+++ /dev/null
@@ -1,3 +0,0 @@
-Testing standard cons.
-Evaluation 0: List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
-Evaluation 1: List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
diff --git a/test/files/run/concurrent-stream.scala b/test/files/run/concurrent-stream.scala
deleted file mode 100644
index 9d5ba0428e..0000000000
--- a/test/files/run/concurrent-stream.scala
+++ /dev/null
@@ -1,37 +0,0 @@
-// test concurrent calls to Stream.tail
-@deprecated("Suppress warnings", since="2.11")
-object Test {
-
- def slowRange(from: Int, until: Int, cons: (Int, => Stream[Int]) => Stream[Int]): Stream[Int] = {
- var current = from
- def next: Stream[Int] = {
- Thread.sleep(100)
- if (current >= until) Stream.empty
- else {
- val stream = cons(current, next)
- current += 1
- stream
- }
- }
- next
- }
-
- def testCons(cons: (Int, => Stream[Int]) => Stream[Int]): Unit = {
- import scala.actors.Actor._
-
- val stream = slowRange(0, 10, cons)
- val main = self
- actor { main ! stream.toList }
- actor { main ! stream.toList }
- val eval0 = receive { case list: List[Int @unchecked] => list }
- val eval1 = receive { case list: List[Int @unchecked] => list }
- println("Evaluation 0: " + eval0)
- println("Evaluation 1: " + eval1)
- }
-
- def main(args: Array[String]) {
- println("Testing standard cons.")
- testCons(Stream.cons.apply(_, _))
- }
-}
-
diff --git a/test/files/run/duration-coarsest.scala b/test/files/run/duration-coarsest.scala
index 51cb79287a..81fbb3cc84 100644
--- a/test/files/run/duration-coarsest.scala
+++ b/test/files/run/duration-coarsest.scala
@@ -25,4 +25,7 @@ object Test extends App {
23 hours,
40 days
) foreach (x => assert(x == x.toCoarsest, x))
-} \ No newline at end of file
+
+ // toCoarsest on a FiniteDuration should return a FiniteDuration
+ val finite: FiniteDuration = 1.second.toCoarsest
+}
diff --git a/test/files/run/future-flatmap-exec-count.check b/test/files/run/future-flatmap-exec-count.check
index dd9dce64ed..7065c133e0 100644
--- a/test/files/run/future-flatmap-exec-count.check
+++ b/test/files/run/future-flatmap-exec-count.check
@@ -1,3 +1,4 @@
+warning: there was one deprecation warning; re-run with -deprecation for details
mapping
execute()
flatmapping
diff --git a/test/files/run/inline-ex-handlers.check b/test/files/run/inline-ex-handlers.check
index 7c885d2cc9..27a277d314 100644
--- a/test/files/run/inline-ex-handlers.check
+++ b/test/files/run/inline-ex-handlers.check
@@ -123,12 +123,12 @@
300 RETURN(UNIT)
@@ -583,6 +603,6 @@
with finalizer: null
-- catch (Throwable) in ArrayBuffer(7, 9, 10) starting at: 6
-+ catch (Throwable) in ArrayBuffer(7, 9, 10, 11) starting at: 6
+- catch (Throwable) in Vector(7, 9, 10) starting at: 6
++ catch (Throwable) in Vector(7, 9, 10, 11) starting at: 6
consisting of blocks: List(6)
with finalizer: null
-- catch (Throwable) in ArrayBuffer(4, 6, 7, 9, 10) starting at: 3
-+ catch (Throwable) in ArrayBuffer(4, 6, 7, 9, 10, 11, 12) starting at: 3
+- catch (Throwable) in Vector(4, 6, 7, 9, 10) starting at: 3
++ catch (Throwable) in Vector(4, 6, 7, 9, 10, 11, 12) starting at: 3
consisting of blocks: List(3)
@@ -618,3 +638,3 @@
startBlock: 1
@@ -171,8 +171,8 @@
}
@@ -690,3 +730,3 @@
with finalizer: null
-- catch (<none>) in ArrayBuffer(4, 5, 6, 8) starting at: 3
-+ catch (<none>) in ArrayBuffer(4, 5, 6, 8, 10) starting at: 3
+- catch (<none>) in Vector(4, 5, 6, 8) starting at: 3
++ catch (<none>) in Vector(4, 5, 6, 8, 10) starting at: 3
consisting of blocks: List(3)
@@ -714,5 +754,5 @@
def main(args: Array[String] (ARRAY[REF(class String)])): Unit {
@@ -276,12 +276,12 @@
}
@@ -852,6 +918,6 @@
with finalizer: null
-- catch (Throwable) in ArrayBuffer(13, 14, 15, 18, 20, 21, 23) starting at: 4
-+ catch (Throwable) in ArrayBuffer(13, 14, 15, 18, 20, 21, 23, 25) starting at: 4
+- catch (Throwable) in Vector(13, 14, 15, 18, 20, 21, 23) starting at: 4
++ catch (Throwable) in Vector(13, 14, 15, 18, 20, 21, 23, 25) starting at: 4
consisting of blocks: List(9, 8, 6, 5, 4)
with finalizer: null
-- catch (<none>) in ArrayBuffer(4, 5, 6, 9, 13, 14, 15, 18, 20, 21, 23) starting at: 3
-+ catch (<none>) in ArrayBuffer(4, 5, 6, 9, 13, 14, 15, 18, 20, 21, 23, 25, 26) starting at: 3
+- catch (<none>) in Vector(4, 5, 6, 9, 13, 14, 15, 18, 20, 21, 23) starting at: 3
++ catch (<none>) in Vector(4, 5, 6, 9, 13, 14, 15, 18, 20, 21, 23, 25, 26) starting at: 3
consisting of blocks: List(3)
@@ -879,5 +945,5 @@
def main(args: Array[String] (ARRAY[REF(class String)])): Unit {
@@ -317,8 +317,8 @@
127 CALL_METHOD scala.Predef.println (dynamic)
@@ -964,3 +1034,3 @@
with finalizer: null
-- catch (IllegalArgumentException) in ArrayBuffer(6, 7, 8, 11, 13, 14, 16) starting at: 3
-+ catch (IllegalArgumentException) in ArrayBuffer(6, 7, 8, 11, 13, 14, 16, 17) starting at: 3
+- catch (IllegalArgumentException) in Vector(6, 7, 8, 11, 13, 14, 16) starting at: 3
++ catch (IllegalArgumentException) in Vector(6, 7, 8, 11, 13, 14, 16, 17) starting at: 3
consisting of blocks: List(3)
@@ -988,5 +1058,5 @@
def main(args: Array[String] (ARRAY[REF(class String)])): Unit {
diff --git a/test/files/run/lub-visibility.check b/test/files/run/lub-visibility.check
index 70734966f0..135cb3cb76 100644
--- a/test/files/run/lub-visibility.check
+++ b/test/files/run/lub-visibility.check
@@ -6,6 +6,6 @@ scala> // should infer List[scala.collection.immutable.Seq[Nothing]]
scala> // but reverted that for SI-5534.
scala> val x = List(List(), Vector())
-x: List[scala.collection.immutable.Seq[Nothing] with scala.collection.AbstractSeq[Nothing] with java.io.Serializable] = List(List(), Vector())
+x: List[scala.collection.immutable.Seq[Nothing] with scala.collection.AbstractSeq[Nothing] with Serializable] = List(List(), Vector())
scala> :quit
diff --git a/test/files/run/nothingTypeDce.flags b/test/files/run/nothingTypeDce.flags
index d85321ca0e..fde52cc7df 100644
--- a/test/files/run/nothingTypeDce.flags
+++ b/test/files/run/nothingTypeDce.flags
@@ -1 +1 @@
--target:jvm-1.6 -Ybackend:GenBCode -Yopt:unreachable-code
+-Ybackend:GenBCode -Yopt:unreachable-code
diff --git a/test/files/run/nothingTypeDce.scala b/test/files/run/nothingTypeDce.scala
index 5f3692fd33..92d3ca6f89 100644
--- a/test/files/run/nothingTypeDce.scala
+++ b/test/files/run/nothingTypeDce.scala
@@ -1,7 +1,6 @@
// See comment in BCodeBodyBuilder
-// -target:jvm-1.6 -Ybackend:GenBCode -Yopt:unreachable-code
-// target enables stack map frames generation
+// -Ybackend:GenBCode -Yopt:unreachable-code
class C {
// can't just emit a call to ???, that returns value of type Nothing$ (not Int).
diff --git a/test/files/run/nothingTypeNoFramesNoDce.check b/test/files/run/nothingTypeNoFramesNoDce.check
deleted file mode 100644
index b1d08b45ff..0000000000
--- a/test/files/run/nothingTypeNoFramesNoDce.check
+++ /dev/null
@@ -1 +0,0 @@
-warning: -target:jvm-1.5 is deprecated: use target for Java 1.6 or above.
diff --git a/test/files/run/nothingTypeNoFramesNoDce.flags b/test/files/run/nothingTypeNoFramesNoDce.flags
deleted file mode 100644
index a035c86179..0000000000
--- a/test/files/run/nothingTypeNoFramesNoDce.flags
+++ /dev/null
@@ -1 +0,0 @@
--target:jvm-1.5 -Ybackend:GenBCode -Yopt:l:none -deprecation
diff --git a/test/files/run/nothingTypeNoFramesNoDce.scala b/test/files/run/nothingTypeNoFramesNoDce.scala
deleted file mode 100644
index 3d1298303a..0000000000
--- a/test/files/run/nothingTypeNoFramesNoDce.scala
+++ /dev/null
@@ -1,61 +0,0 @@
-// See comment in BCodeBodyBuilder
-
-// -target:jvm-1.5 -Ybackend:GenBCode -Yopt:l:none
-// target disables stack map frame generation. in this mode, the ClssWriter just emits dead code as is.
-
-class C {
- // can't just emit a call to ???, that returns value of type Nothing$ (not Int).
- def f1: Int = ???
-
- def f2: Int = throw new Error("")
-
- def f3(x: Boolean) = {
- var y = 0
- // cannot assign an object of type Nothing$ to Int
- if (x) y = ???
- else y = 1
- y
- }
-
- def f4(x: Boolean) = {
- var y = 0
- // tests that whatever is emitted after the throw is valid (what? depends on opts, presence of stack map frames)
- if (x) y = throw new Error("")
- else y = 1
- y
- }
-
- def f5(x: Boolean) = {
- // stack heights need to be the smae. ??? looks to the jvm like returning a value of
- // type Nothing$, need to drop or throw it.
- println(
- if (x) { ???; 10 }
- else 20
- )
- }
-
- def f6(x: Boolean) = {
- println(
- if (x) { throw new Error(""); 10 }
- else 20
- )
- }
-
- def f7(x: Boolean) = {
- println(
- if (x) throw new Error("")
- else 20
- )
- }
-
- def f8(x: Boolean) = {
- println(
- if (x) throw new Error("")
- else 20
- )
- }
-}
-
-object Test extends App {
- new C()
-}
diff --git a/test/files/run/nothingTypeNoOpt.flags b/test/files/run/nothingTypeNoOpt.flags
index b3b518051b..d3e4d61e19 100644
--- a/test/files/run/nothingTypeNoOpt.flags
+++ b/test/files/run/nothingTypeNoOpt.flags
@@ -1 +1 @@
--target:jvm-1.6 -Ybackend:GenBCode -Yopt:l:none
+-Ybackend:GenBCode -Yopt:l:none
diff --git a/test/files/run/repl-javap-app.check b/test/files/run/repl-javap-app.check
deleted file mode 100644
index eb3718f44b..0000000000
--- a/test/files/run/repl-javap-app.check
+++ /dev/null
@@ -1,63 +0,0 @@
-#partest java6
-Welcome to Scala
-Type in expressions to have them evaluated.
-Type :help for more information.
-
-scala> :javap -app MyApp$
-public final void delayedEndpoint$MyApp$1();
- Code:
- Stack=2, Locals=1, Args_size=1
- 0: getstatic #XX; //Field scala/Console$.MODULE$:Lscala/Console$;
- 3: ldc #XX; //String Hello, delayed world.
- 5: invokevirtual #XX; //Method scala/Console$.println:(Ljava/lang/Object;)V
- 8: return
- LocalVariableTable:
- Start Length Slot Name Signature
- 0 9 0 this LMyApp$;
-
-scala> :quit
-#partest java7
-Welcome to Scala
-Type in expressions to have them evaluated.
-Type :help for more information.
-
-scala> :javap -app MyApp$
- public final void delayedEndpoint$MyApp$1();
- flags: ACC_PUBLIC, ACC_FINAL
- Code:
- stack=2, locals=1, args_size=1
- 0: getstatic #XX // Field scala/Console$.MODULE$:Lscala/Console$;
- 3: ldc #XX // String Hello, delayed world.
- 5: invokevirtual #XX // Method scala/Console$.println:(Ljava/lang/Object;)V
- 8: return
- LocalVariableTable:
- Start Length Slot Name Signature
- 0 9 0 this LMyApp$;
- LineNumberTable:
- line 5: 0
-}
-
-scala> :quit
-#partest java8
-Welcome to Scala
-Type in expressions to have them evaluated.
-Type :help for more information.
-
-scala> :javap -app MyApp$
- public final void delayedEndpoint$MyApp$1();
- descriptor: ()V
- flags: ACC_PUBLIC, ACC_FINAL
- Code:
- stack=2, locals=1, args_size=1
- 0: getstatic #XX // Field scala/Console$.MODULE$:Lscala/Console$;
- 3: ldc #XX // String Hello, delayed world.
- 5: invokevirtual #XX // Method scala/Console$.println:(Ljava/lang/Object;)V
- 8: return
- LocalVariableTable:
- Start Length Slot Name Signature
- 0 9 0 this LMyApp$;
- LineNumberTable:
- line 5: 0
-}
-
-scala> :quit
diff --git a/test/files/run/repl-javap-app.scala b/test/files/run/repl-javap-app.scala
deleted file mode 100644
index ad6076c2d5..0000000000
--- a/test/files/run/repl-javap-app.scala
+++ /dev/null
@@ -1,21 +0,0 @@
-
-import scala.tools.partest.ReplTest
-
-object MyApp extends App {
- Console println "Hello, delayed world."
-}
-
-object Test extends ReplTest {
- def code = ":javap -app MyApp$"
-
- override def welcoming = true
-
- // The constant pool indices are not the same for GenASM / GenBCode, so
- // replacing the exact numbers by XX.
- lazy val hasConstantPoolRef = """(.*)(#\d\d)(.*)""".r
-
- override def normalize(s: String) = s match {
- case hasConstantPoolRef(start, ref, end) => start + "#XX" + end
- case _ => super.normalize(s)
- }
-}
diff --git a/test/files/run/t2251b.check b/test/files/run/t2251b.check
index 4231fc6ea6..b60698d605 100644
--- a/test/files/run/t2251b.check
+++ b/test/files/run/t2251b.check
@@ -1,4 +1,4 @@
-TypeTag[List[scala.collection.immutable.LinearSeq[B[_ >: D with C <: B[_ >: D with C <: A]]] with scala.collection.AbstractSeq[B[_ >: D with C <: B[_ >: D with C <: A]]] with java.io.Serializable]]
+TypeTag[List[scala.collection.immutable.LinearSeq[B[_ >: D with C <: B[_ >: D with C <: A]]] with scala.collection.AbstractSeq[B[_ >: D with C <: B[_ >: D with C <: A]]] with Serializable]]
TypeTag[List[scala.collection.immutable.Iterable[B[_ >: F with E with D with C <: B[_ >: F with E with D with C <: A]]] with F with Int => Any]]
TypeTag[List[scala.collection.immutable.Seq[B[_ >: D with C <: B[_ >: D with C <: A]]] with scala.collection.AbstractSeq[B[_ >: D with C <: B[_ >: D with C <: A]]] with Serializable]]
TypeTag[List[scala.collection.Set[_ >: G with F <: B[_ >: G with F <: B[_ >: G with F <: A]]]]]
@@ -6,6 +6,6 @@ TypeTag[List[scala.collection.Set[_ >: G with F <: B[_ >: G with F <: B[_ >: G w
TypeTag[List[scala.collection.Set[_ >: G with F <: B[_ >: G with F <: B[_ >: G with F <: A]]]]]
TypeTag[List[Seq[B[_ >: G with F <: B[_ >: G with F <: A]]]]]
TypeTag[List[scala.collection.Map[_ >: F with C <: B[_ >: F with C <: B[_ >: F with C <: A]], B[_ >: G with D <: B[_ >: G with D <: A]]]]]
-TypeTag[List[scala.collection.AbstractSeq[B[_ >: G with F <: B[_ >: G with F <: A]]] with scala.collection.LinearSeq[B[_ >: G with F <: B[_ >: G with F <: A]]] with java.io.Serializable]]
+TypeTag[List[scala.collection.AbstractSeq[B[_ >: G with F <: B[_ >: G with F <: A]]] with scala.collection.LinearSeq[B[_ >: G with F <: B[_ >: G with F <: A]]] with Serializable]]
TypeTag[List[Seq[B[_ >: G with F <: B[_ >: G with F <: A]]]]]
TypeTag[List[Seq[B[_ >: G with F <: B[_ >: G with F <: A]]]]]
diff --git a/test/files/run/t4332.scala b/test/files/run/t4332.scala
index 5a67922911..1c7e7d73de 100644
--- a/test/files/run/t4332.scala
+++ b/test/files/run/t4332.scala
@@ -12,7 +12,7 @@ object Test extends DirectTest {
}
def isExempt(sym: Symbol) = {
- val exempt = Set("view", "repr", "sliceWithKnownDelta", "sliceWithKnownBound", "transform")
+ val exempt = Set("view", "repr", "sliceWithKnownDelta", "sliceWithKnownBound", "transform", "filterImpl")
(exempt contains sym.name.decoded)
}
diff --git a/test/files/run/t6827.check b/test/files/run/t6827.check
index 3a3a71c67d..4889e05be8 100644
--- a/test/files/run/t6827.check
+++ b/test/files/run/t6827.check
@@ -1,6 +1,6 @@
-start at -5: java.lang.IllegalArgumentException: requirement failed: start -5 out of range 10
-start at -1: java.lang.IllegalArgumentException: requirement failed: start -1 out of range 10
-start at limit: java.lang.IllegalArgumentException: requirement failed: start 10 out of range 10
+start at -5: java.lang.ArrayIndexOutOfBoundsException: -5
+start at -1: java.lang.ArrayIndexOutOfBoundsException: -1
+start at limit: ok
start at limit-1: ok
first 10: ok
read all: ok
@@ -8,8 +8,8 @@ test huge len: ok
5 from 5: ok
20 from 5: ok
test len overflow: ok
-start beyond limit: java.lang.IllegalArgumentException: requirement failed: start 30 out of range 10
+start beyond limit: ok
read 0: ok
read -1: ok
-invalid read 0: java.lang.IllegalArgumentException: requirement failed: start 30 out of range 10
-invalid read -1: java.lang.IllegalArgumentException: requirement failed: start 30 out of range 10
+invalid read 0: ok
+invalid read -1: ok
diff --git a/test/files/run/t6827.scala b/test/files/run/t6827.scala
index 8e17af09e2..eb020711bb 100644
--- a/test/files/run/t6827.scala
+++ b/test/files/run/t6827.scala
@@ -31,4 +31,24 @@ object Test extends App {
// okay, see SI-7128
"...".toIterator.copyToArray(new Array[Char](0), 0, 0)
+
+
+ // Bonus test from @som-snytt to check for overflow in
+ // index calculations.
+ def testOverflow(start: Int, len: Int, expected: List[Char]) {
+ def copyFromIterator = {
+ val arr = Array.fill[Char](3)('-')
+ "abc".toIterator.copyToArray(arr, start, len)
+ arr.toList
+ }
+ def copyFromArray = {
+ val arr = Array.fill[Char](3)('-')
+ "abc".toArray.copyToArray(arr, start, len)
+ arr.toList
+ }
+ assert(copyFromIterator == expected)
+ assert(copyFromArray == expected)
+ }
+ testOverflow(1, Int.MaxValue - 1, "-ab".toList)
+ testOverflow(1, Int.MaxValue, "-ab".toList)
}
diff --git a/test/files/run/t7521/Test.scala b/test/files/run/t7521/Test.scala
new file mode 100644
index 0000000000..e9816ad6cb
--- /dev/null
+++ b/test/files/run/t7521/Test.scala
@@ -0,0 +1,5 @@
+object Test {
+ def main(args: Array[String]): Unit = {
+ new Wrapper(new Array[Int](1))
+ }
+}
diff --git a/test/files/run/t7521/Wrapper.scala b/test/files/run/t7521/Wrapper.scala
new file mode 100644
index 0000000000..0b923f8924
--- /dev/null
+++ b/test/files/run/t7521/Wrapper.scala
@@ -0,0 +1 @@
+class Wrapper[Repr](val xs: Repr) extends AnyVal
diff --git a/test/files/run/t7521b.check b/test/files/run/t7521b.check
new file mode 100644
index 0000000000..4d96df106d
--- /dev/null
+++ b/test/files/run/t7521b.check
@@ -0,0 +1,7 @@
+= Java Erased Signatures =
+public int C.a(Wrapper)
+public int C.b(Wrapper)
+
+= Java Generic Signatures =
+public int C.a(Wrapper<int[]>)
+public int C.b(Wrapper<java.lang.Object>)
diff --git a/test/files/run/t7521b.scala b/test/files/run/t7521b.scala
new file mode 100644
index 0000000000..c9e27f28b4
--- /dev/null
+++ b/test/files/run/t7521b.scala
@@ -0,0 +1,20 @@
+class Wrapper[X](x: X)
+
+class C {
+ def a(w: Wrapper[Array[Int]]) = 0
+ def b(w: Wrapper[Int]) = 0
+}
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ val c = new C
+ c.a(new Wrapper(Array(1, 2)))
+ c.b(new Wrapper(1))
+
+ val methods = classOf[C].getDeclaredMethods.sortBy(_.getName)
+ println("= Java Erased Signatures =")
+ println(methods.mkString("\n"))
+ println("\n= Java Generic Signatures =")
+ println(methods.map(_.toGenericString).mkString("\n"))
+ }
+}
diff --git a/test/files/run/t7775.scala b/test/files/run/t7775.scala
index 48b0d89974..bc69064e17 100644
--- a/test/files/run/t7775.scala
+++ b/test/files/run/t7775.scala
@@ -1,3 +1,45 @@
+import scala.concurrent._, duration._
+import ExecutionContext.Implicits.global
+import scala.tools.reflect.WrappedProperties.AccessControl._
+import java.util.concurrent.CyclicBarrier
+
+object Test extends App {
+ @volatile var done = false
+ val barrier = new CyclicBarrier(2)
+
+ val probe = Future {
+ val attempts = 1024 // previously, failed after a few
+ def fail(i: Int) = s"Failed at $i"
+ barrier.await()
+ for (i <- 1 to attempts ; p <- systemProperties)
+ p match { case (k, v) => assert (k != null && v != null, fail(i)) }
+ }
+ probe onComplete {
+ case _ => done = true
+ }
+
+ System.setProperty("foo", "fooz")
+ System.setProperty("bar", "barz")
+ barrier.await() // just for fun, wait to start mucking with properties
+
+ // continually modify properties trying to break live iteration over sys props
+ // hint: don't iterate lively over sys props
+ var alt = true
+ while (!done) {
+ if (alt) {
+ System.getProperties.remove("foo")
+ System.setProperty("bar", "barz")
+ alt = false
+ } else {
+ System.getProperties.remove("bar")
+ System.setProperty("foo", "fooz")
+ alt = true
+ }
+ }
+ Await.result(probe, Duration.Inf)
+}
+
+/*
import scala.concurrent.{duration, Future, Await, ExecutionContext}
import scala.tools.nsc.Settings
import ExecutionContext.Implicits.global
@@ -15,3 +57,4 @@ object Test {
Await.result(compiler, duration.Duration.Inf)
}
}
+*/
diff --git a/test/files/run/t8575.scala b/test/files/run/t8575.scala
new file mode 100644
index 0000000000..fb8f603f3e
--- /dev/null
+++ b/test/files/run/t8575.scala
@@ -0,0 +1,32 @@
+class E[F]
+class A
+class B
+class C
+
+trait TypeMember {
+ type X
+
+ // This call throws an AbstractMethodError, because it invokes the erasure of
+ // consume(X): Unit that is consume(Object): Unit. But the corresponding
+ // bridge method is not generated.
+ consume(value)
+
+ def value: X
+ def consume(x: X): Unit
+}
+
+object Test extends TypeMember {
+ type F = A with B
+
+ // works if replaced by type X = E[A with B with C]
+ type X = E[F with C]
+
+ def value = new E[F with C]
+
+ // This call passes, since it invokes consume(E): Unit
+ def consume(x: X) {}
+
+ def main(args: Array[String]) {
+ consume(value)
+ }
+}
diff --git a/test/files/run/t8575b.scala b/test/files/run/t8575b.scala
new file mode 100644
index 0000000000..0d731ccf9f
--- /dev/null
+++ b/test/files/run/t8575b.scala
@@ -0,0 +1,17 @@
+class A
+class B
+class C
+
+object Test {
+ type F = A with B
+
+ def main(args: Array[String]) {
+ import reflect.runtime.universe._
+ val t1 = typeOf[F with C]
+ val t2 = typeOf[(A with B) with C]
+ val t3 = typeOf[A with B with C]
+ assert(t1 =:= t2)
+ assert(t2 =:= t3)
+ assert(t3 =:= t1)
+ }
+}
diff --git a/test/files/run/t8575c.scala b/test/files/run/t8575c.scala
new file mode 100644
index 0000000000..8219952299
--- /dev/null
+++ b/test/files/run/t8575c.scala
@@ -0,0 +1,23 @@
+class C
+
+trait TypeMember {
+ type X
+ type Y
+ type Z
+}
+
+object Test extends TypeMember {
+ type A = X with Y
+ type B = Z with A
+ type F = A with B
+
+ def main(args: Array[String]) {
+ import reflect.runtime.universe._
+ val t1 = typeOf[F with C]
+ val t2 = typeOf[(A with B) with C]
+ val t3 = typeOf[A with B with C]
+ assert(t1 =:= t2)
+ assert(t2 =:= t3)
+ assert(t3 =:= t1)
+ }
+}
diff --git a/test/files/run/t8710.scala b/test/files/run/t8710.scala
new file mode 100644
index 0000000000..15aab5b8a4
--- /dev/null
+++ b/test/files/run/t8710.scala
@@ -0,0 +1,17 @@
+class Bar(val x: Int) extends AnyVal {
+ def f: String = f(0)
+ private def f(x: Int): String = ""
+}
+
+class Baz(val x: Int) extends AnyVal {
+ def f: String = "123"
+ private def f(x: Int): String = ""
+}
+object Baz {
+ def x(b: Baz) = b.f(0)
+}
+
+object Test extends App {
+ new Bar(23).f
+ new Baz(23).f
+}
diff --git a/test/files/run/t8764.check b/test/files/run/t8764.check
deleted file mode 100644
index 6260069602..0000000000
--- a/test/files/run/t8764.check
+++ /dev/null
@@ -1,5 +0,0 @@
-IntOnly: should return an unboxed int
-Int: int
-IntAndDouble: should just box and return Anyval
-Double: class java.lang.Double
-Int: class java.lang.Integer
diff --git a/test/files/run/t8764.flags b/test/files/run/t8764.flags
deleted file mode 100644
index 48fd867160..0000000000
--- a/test/files/run/t8764.flags
+++ /dev/null
@@ -1 +0,0 @@
--Xexperimental
diff --git a/test/files/run/t8764.scala b/test/files/run/t8764.scala
deleted file mode 100644
index decc658f6e..0000000000
--- a/test/files/run/t8764.scala
+++ /dev/null
@@ -1,16 +0,0 @@
-object Test extends App {
-case class IntOnly(i: Int, j: Int)
-
-println("IntOnly: should return an unboxed int")
-val a = IntOnly(1, 2)
-val i: Int = a.productElement(0)
-println(s"Int: ${a.productElement(0).getClass}")
-
-case class IntAndDouble(i: Int, d: Double)
-
-println("IntAndDouble: should just box and return Anyval")
-val b = IntAndDouble(1, 2.0)
-val j: AnyVal = b.productElement(0)
-println(s"Double: ${b.productElement(1).getClass}")
-println(s"Int: ${b.productElement(0).getClass}")
-}
diff --git a/test/files/run/t8918-unary-ids.scala b/test/files/run/t8918-unary-ids.scala
new file mode 100644
index 0000000000..3aa990f72c
--- /dev/null
+++ b/test/files/run/t8918-unary-ids.scala
@@ -0,0 +1,49 @@
+
+
+import scala.tools.partest.SessionTest
+
+// Taking unary ids as plain
+object Test extends SessionTest {
+ def session =
+"""Type in expressions to have them evaluated.
+Type :help for more information.
+
+scala> val - = 42
+-: Int = 42
+
+scala> val i = -
+i: Int = 42
+
+scala> - { 42 }
+res0: Int = -42
+
+scala> - if (true) 1 else 2
+<console>:1: error: illegal start of simple expression
+- if (true) 1 else 2
+ ^
+
+scala> - - 1
+<console>:1: error: ';' expected but integer literal found.
+- - 1
+ ^
+
+scala> -.-(1)
+res1: Int = 41
+
+scala> -
+res2: Int = 42
+
+scala> - -
+res3: Int = -42
+
+scala> + -
+res4: Int = 42
+
+scala> object X { def -(i: Int) = 42 - i ; def f(g: Int => Int) = g(7) ; def j = f(-) }
+defined object X
+
+scala> X.j
+res5: Int = 35
+
+scala> :quit"""
+}
diff --git a/test/files/run/t8944/A_1.scala b/test/files/run/t8944/A_1.scala
new file mode 100644
index 0000000000..7ff80327b0
--- /dev/null
+++ b/test/files/run/t8944/A_1.scala
@@ -0,0 +1 @@
+case class A(private val x: String)
diff --git a/test/files/run/t8944/A_2.scala b/test/files/run/t8944/A_2.scala
new file mode 100644
index 0000000000..3dcdea1583
--- /dev/null
+++ b/test/files/run/t8944/A_2.scala
@@ -0,0 +1,6 @@
+case class Other(private val x: String) // consume a fresh name suffix
+
+// the param accessor will now be called "x$2",
+// whereas the previously compiled client expects it to be called
+// x$1
+case class A(private val x: String)
diff --git a/test/files/run/t8944/Test_1.scala b/test/files/run/t8944/Test_1.scala
new file mode 100644
index 0000000000..fe466693cf
--- /dev/null
+++ b/test/files/run/t8944/Test_1.scala
@@ -0,0 +1,3 @@
+object Test extends App {
+ val A("") = new A("")
+}
diff --git a/test/files/run/t8944b.scala b/test/files/run/t8944b.scala
new file mode 100644
index 0000000000..f469122ce6
--- /dev/null
+++ b/test/files/run/t8944b.scala
@@ -0,0 +1,9 @@
+case class A(private var foo: Any) {
+ def m = { def foo = 42 /*will be lamba lifted to `A#foo$1`*/ }
+}
+object Test {
+ def main(args: Array[String]): Unit = {
+ val A("") = new A("")
+ new A("").m
+ }
+}
diff --git a/test/files/run/t8944c.check b/test/files/run/t8944c.check
new file mode 100644
index 0000000000..7738f76980
--- /dev/null
+++ b/test/files/run/t8944c.check
@@ -0,0 +1,5 @@
+private java.lang.Object Foo.ant()
+public java.lang.Object Foo.ant$access$0()
+private scala.collection.Seq Foo.cat()
+public scala.collection.Seq Foo.cat$access$2()
+public java.lang.Object Foo.elk()
diff --git a/test/files/run/t8944c.scala b/test/files/run/t8944c.scala
new file mode 100644
index 0000000000..95c2143851
--- /dev/null
+++ b/test/files/run/t8944c.scala
@@ -0,0 +1,8 @@
+case class Foo[A](private val ant: Any, elk: Any, private val cat: A*)
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ def pred(name: String) = Set("ant", "elk", "cat").exists(name contains _)
+ println(classOf[Foo[_]].getDeclaredMethods.filter(m => pred(m.getName)).sortBy(_.getName).mkString("\n"))
+ }
+}
diff --git a/test/files/run/t8955.scala b/test/files/run/t8955.scala
new file mode 100644
index 0000000000..afa31aa5d7
--- /dev/null
+++ b/test/files/run/t8955.scala
@@ -0,0 +1,12 @@
+import scala.collection.parallel.immutable.ParSet
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ for (i <- 1 to 2000) test()
+ }
+
+ def test() {
+ ParSet[Int]((1 to 10000): _*) foreach (x => ()) // hangs non deterministically
+ }
+}
+
diff --git a/test/files/run/t9174.check b/test/files/run/t9174.check
new file mode 100644
index 0000000000..9320a081ff
--- /dev/null
+++ b/test/files/run/t9174.check
@@ -0,0 +1,19 @@
+Type in expressions to have them evaluated.
+Type :help for more information.
+
+scala> import scala.util.{Success, Failure}
+import scala.util.{Success, Failure}
+
+scala> def f1(b: Boolean) = if (b) Left(1) else Right(2)
+f1: (b: Boolean)scala.util.Either[Int,Int]
+
+scala> def f2(b: Boolean) = if (b) Nil else 1 :: Nil
+f2: (b: Boolean)List[Int]
+
+scala> def f3(b: Boolean) = if (b) Stream.Empty else new Stream.Cons(1, Stream.Empty)
+f3: (b: Boolean)scala.collection.immutable.Stream[Int]
+
+scala> def f4(b: Boolean) = if (b) Success(1) else Failure(new Exception(""))
+f4: (b: Boolean)scala.util.Try[Int]
+
+scala> :quit
diff --git a/test/files/run/t9174.scala b/test/files/run/t9174.scala
new file mode 100644
index 0000000000..0c70e9bca9
--- /dev/null
+++ b/test/files/run/t9174.scala
@@ -0,0 +1,11 @@
+import scala.tools.partest.ReplTest
+
+object Test extends ReplTest {
+ def code = """
+ |import scala.util.{Success, Failure}
+ |def f1(b: Boolean) = if (b) Left(1) else Right(2)
+ |def f2(b: Boolean) = if (b) Nil else 1 :: Nil
+ |def f3(b: Boolean) = if (b) Stream.Empty else new Stream.Cons(1, Stream.Empty)
+ |def f4(b: Boolean) = if (b) Success(1) else Failure(new Exception(""))
+ |""".stripMargin
+}
diff --git a/test/files/run/t9200/Test.java b/test/files/run/t9200/Test.java
new file mode 100644
index 0000000000..8ff0314f6c
--- /dev/null
+++ b/test/files/run/t9200/Test.java
@@ -0,0 +1,6 @@
+public class Test {
+ public static void main(String[] args) {
+ new C1(new C2()); // Was NoSuchMethodError
+ }
+}
+
diff --git a/test/files/run/t9200/test.scala b/test/files/run/t9200/test.scala
new file mode 100644
index 0000000000..6fa7e91571
--- /dev/null
+++ b/test/files/run/t9200/test.scala
@@ -0,0 +1,12 @@
+trait W
+
+trait T1
+trait T2 extends T1
+
+object O1 {
+ type t = T1 with T2
+}
+
+class C1[w<:W](o: O1.t)
+
+class C2 extends T1 with T2
diff --git a/test/files/scalacheck/concurrent-map.scala b/test/files/scalacheck/concurrent-map.scala
new file mode 100755
index 0000000000..7c9b8d4169
--- /dev/null
+++ b/test/files/scalacheck/concurrent-map.scala
@@ -0,0 +1,76 @@
+
+
+
+import java.util.concurrent._
+import scala.collection._
+import scala.collection.JavaConverters._
+import org.scalacheck._
+import org.scalacheck.Prop._
+import org.scalacheck.Gen._
+
+
+
+case class Wrap(i: Int) {
+ override def hashCode = i * 0x9e3775cd
+}
+
+
+object Test extends Properties("concurrent.TrieMap") {
+
+ /* generators */
+
+ val sizes = choose(0, 20000)
+
+ val threadCounts = choose(2, 16)
+
+ val threadCountsAndSizes = for {
+ p <- threadCounts
+ sz <- sizes
+ } yield (p, sz);
+
+
+ /* helpers */
+
+ def inParallel[T](totalThreads: Int)(body: Int => T): Seq[T] = {
+ val threads = for (idx <- 0 until totalThreads) yield new Thread {
+ setName("ParThread-" + idx)
+ private var res: T = _
+ override def run() {
+ res = body(idx)
+ }
+ def result = {
+ this.join()
+ res
+ }
+ }
+
+ threads foreach (_.start())
+ threads map (_.result)
+ }
+
+ property("concurrent getOrElseUpdate insertions") = forAll(threadCounts, sizes) {
+ (p, sz) =>
+ val chm = new ConcurrentHashMap[Wrap, Int]().asScala
+
+ val results = inParallel(p) {
+ idx =>
+ for (i <- 0 until sz) yield chm.getOrElseUpdate(new Wrap(i), idx)
+ }
+
+ val resultSets = for (i <- 0 until sz) yield results.map(_(i)).toSet
+ val largerThanOne = resultSets.zipWithIndex.find(_._1.size != 1)
+ val allThreadsAgreeOnWhoInserted = {
+ largerThanOne == None
+ } :| s"$p threads agree on who inserted [disagreement (differentResults, position) = $largerThanOne]"
+
+ allThreadsAgreeOnWhoInserted
+ }
+
+
+}
+
+
+
+
+
+
diff --git a/test/junit/scala/collection/IteratorTest.scala b/test/junit/scala/collection/IteratorTest.scala
index 1c1e50aed9..b0639ef365 100644
--- a/test/junit/scala/collection/IteratorTest.scala
+++ b/test/junit/scala/collection/IteratorTest.scala
@@ -135,6 +135,20 @@ class IteratorTest {
assertEquals(3, List(1, 2, 3, 4, 5).iterator.indexWhere { x: Int => x >= 4 })
assertEquals(-1, List(1, 2, 3, 4, 5).iterator.indexWhere { x: Int => x >= 16 })
}
+ @Test def indexOfFrom(): Unit = {
+ assertEquals(1, List(1, 2, 3, 4, 5).iterator.indexOf(2, 0))
+ assertEquals(1, List(1, 2, 3, 4, 5).iterator.indexOf(2, 1))
+ assertEquals(-1, List(1, 2, 3, 4, 5).iterator.indexOf(2, 2))
+ assertEquals(4, List(1, 2, 3, 2, 1).iterator.indexOf(1, 1))
+ assertEquals(1, List(1, 2, 3, 2, 1).iterator.indexOf(2, 1))
+ }
+ @Test def indexWhereFrom(): Unit = {
+ assertEquals(1, List(1, 2, 3, 4, 5).iterator.indexWhere(_ == 2, 0))
+ assertEquals(1, List(1, 2, 3, 4, 5).iterator.indexWhere(_ == 2, 1))
+ assertEquals(-1, List(1, 2, 3, 4, 5).iterator.indexWhere(_ == 2, 2))
+ assertEquals(4, List(1, 2, 3, 2, 1).iterator.indexWhere(_ < 2, 1))
+ assertEquals(1, List(1, 2, 3, 2, 1).iterator.indexWhere(_ <= 2, 1))
+ }
// iterator-iterate-lazy.scala
// was java.lang.UnsupportedOperationException: tail of empty list
@Test def iterateIsSufficientlyLazy(): Unit = {
@@ -154,6 +168,14 @@ class IteratorTest {
results += (Stream from 1).toIterator.drop(10).toStream.drop(10).toIterator.next()
assertSameElements(List(1,1,21), results)
}
+ // SI-8552
+ @Test def indexOfShouldWorkForTwoParams(): Unit = {
+ assertEquals(1, List(1, 2, 3).iterator.indexOf(2, 0))
+ assertEquals(-1, List(5 -> 0).iterator.indexOf(5, 0))
+ assertEquals(0, List(5 -> 0).iterator.indexOf((5, 0)))
+ assertEquals(-1, List(5 -> 0, 9 -> 2, 0 -> 3).iterator.indexOf(9, 2))
+ assertEquals(1, List(5 -> 0, 9 -> 2, 0 -> 3).iterator.indexOf(9 -> 2))
+ }
// SI-9332
@Test def spanExhaustsLeadingIterator(): Unit = {
def it = Iterator.iterate(0)(_ + 1).take(6)
diff --git a/test/junit/scala/collection/SeqViewTest.scala b/test/junit/scala/collection/SeqViewTest.scala
new file mode 100644
index 0000000000..24474fc4b9
--- /dev/null
+++ b/test/junit/scala/collection/SeqViewTest.scala
@@ -0,0 +1,16 @@
+package scala.collection
+
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.junit.Assert._
+import org.junit.Test
+
+@RunWith(classOf[JUnit4])
+class SeqViewTest {
+
+ @Test
+ def test_SI8691() {
+ // Really just testing to make sure ++: doesn't throw an exception
+ assert( Seq(1,2) ++: Seq(3,4).view == Seq(1,2,3,4) )
+ }
+}
diff --git a/test/junit/scala/collection/SetMapConsistencyTest.scala b/test/junit/scala/collection/SetMapConsistencyTest.scala
index 261c11a98b..0749e61c09 100644
--- a/test/junit/scala/collection/SetMapConsistencyTest.scala
+++ b/test/junit/scala/collection/SetMapConsistencyTest.scala
@@ -529,4 +529,15 @@ class SetMapConsistencyTest {
assert(nit == 4)
assert(nfe == 4)
}
+
+ @Test
+ def test_SI8727() {
+ import scala.tools.testing.AssertUtil._
+ type NSEE = NoSuchElementException
+ val map = Map(0 -> "zero", 1 -> "one")
+ val m = map.filterKeys(i => if (map contains i) true else throw new NSEE)
+ assert{ (m contains 0) && (m get 0).nonEmpty }
+ assertThrows[NSEE]{ m contains 2 }
+ assertThrows[NSEE]{ m get 2 }
+ }
}
diff --git a/test/junit/scala/collection/convert/NullSafetyTest.scala b/test/junit/scala/collection/convert/NullSafetyTest.scala
new file mode 100644
index 0000000000..de5481d9e2
--- /dev/null
+++ b/test/junit/scala/collection/convert/NullSafetyTest.scala
@@ -0,0 +1,279 @@
+package scala.collection.convert
+
+import java.{util => ju, lang => jl}
+import ju.{concurrent => juc}
+
+import org.junit.Test
+import org.junit.experimental.runners.Enclosed
+import org.junit.runner.RunWith
+
+import scala.collection.JavaConversions._
+import scala.collection.JavaConverters._
+import scala.collection.{mutable, concurrent}
+
+@RunWith(classOf[Enclosed])
+object NullSafetyTest {
+
+ /*
+ * Pertinent: SI-9113
+ * Tests to insure that wrappers return null instead of wrapping it as a collection
+ */
+
+ class ToScala {
+
+ @Test def testIteratorWrapping(): Unit = {
+ val nullJIterator: ju.Iterator[AnyRef] = null
+ val iterator: Iterator[AnyRef] = nullJIterator
+
+ assert(iterator == null)
+ }
+
+ @Test def testEnumerationWrapping(): Unit = {
+ val nullJEnumeration: ju.Enumeration[AnyRef] = null
+ val enumeration: Iterator[AnyRef] = nullJEnumeration
+
+ assert(enumeration == null)
+ }
+
+ @Test def testIterableWrapping(): Unit = {
+ val nullJIterable: jl.Iterable[AnyRef] = null
+ val iterable: Iterable[AnyRef] = nullJIterable
+
+ assert(iterable == null)
+ }
+
+ @Test def testCollectionWrapping(): Unit = {
+ val nullJCollection: ju.Collection[AnyRef] = null
+ val collection: Iterable[AnyRef] = nullJCollection
+
+ assert(collection == null)
+ }
+
+ @Test def testBufferWrapping(): Unit = {
+ val nullJList: ju.List[AnyRef] = null
+ val buffer: mutable.Buffer[AnyRef] = nullJList
+
+ assert(buffer == null)
+ }
+
+ @Test def testSetWrapping(): Unit = {
+ val nullJSet: ju.Set[AnyRef] = null
+ val set: mutable.Set[AnyRef] = nullJSet
+
+ assert(set == null)
+ }
+
+ @Test def testMapWrapping(): Unit = {
+ val nullJMap: ju.Map[AnyRef, AnyRef] = null
+ val map: mutable.Map[AnyRef, AnyRef] = nullJMap
+
+ assert(map == null)
+ }
+
+ @Test def testConcurrentMapWrapping(): Unit = {
+ val nullJConMap: juc.ConcurrentMap[AnyRef, AnyRef] = null
+ val conMap: concurrent.Map[AnyRef, AnyRef] = nullJConMap
+
+ assert(conMap == null)
+ }
+
+ @Test def testDictionaryWrapping(): Unit = {
+ val nullJDict: ju.Dictionary[AnyRef, AnyRef] = null
+ val dict: mutable.Map[AnyRef, AnyRef] = nullJDict
+
+ assert(dict == null)
+ }
+
+
+ @Test def testPropertyWrapping(): Unit = {
+ val nullJProps: ju.Properties = null
+ val props: mutable.Map[String, String] = nullJProps
+
+ assert(props == null)
+ }
+
+ @Test def testIteratorDecoration(): Unit = {
+ val nullJIterator: ju.Iterator[AnyRef] = null
+
+ assert(nullJIterator.asScala == null)
+ }
+
+ @Test def testEnumerationDecoration(): Unit = {
+ val nullJEnumeration: ju.Enumeration[AnyRef] = null
+
+ assert(nullJEnumeration.asScala == null)
+ }
+
+ @Test def testIterableDecoration(): Unit = {
+ val nullJIterable: jl.Iterable[AnyRef] = null
+
+ assert(nullJIterable.asScala == null)
+ }
+
+ @Test def testCollectionDecoration(): Unit = {
+ val nullJCollection: ju.Collection[AnyRef] = null
+
+ assert(nullJCollection.asScala == null)
+ }
+
+ @Test def testBufferDecoration(): Unit = {
+ val nullJBuffer: ju.List[AnyRef] = null
+
+ assert(nullJBuffer.asScala == null)
+ }
+
+ @Test def testSetDecoration(): Unit = {
+ val nullJSet: ju.Set[AnyRef] = null
+
+ assert(nullJSet.asScala == null)
+ }
+
+ @Test def testMapDecoration(): Unit = {
+ val nullJMap: ju.Map[AnyRef, AnyRef] = null
+
+ assert(nullJMap.asScala == null)
+ }
+
+ @Test def testConcurrentMapDecoration(): Unit = {
+ val nullJConMap: juc.ConcurrentMap[AnyRef, AnyRef] = null
+
+ assert(nullJConMap.asScala == null)
+ }
+
+ @Test def testDictionaryDecoration(): Unit = {
+ val nullJDict: ju.Dictionary[AnyRef, AnyRef] = null
+
+ assert(nullJDict.asScala == null)
+ }
+
+ @Test def testPropertiesDecoration(): Unit = {
+ val nullJProperties: ju.Properties = null
+
+ assert(nullJProperties.asScala == null)
+ }
+ }
+
+ class ToJava {
+
+ @Test def testIteratorWrapping(): Unit = {
+ val nullIterator: Iterator[AnyRef] = null
+ val jIterator: ju.Iterator[AnyRef] = nullIterator
+
+ assert(jIterator == null)
+ }
+
+ @Test def testEnumerationWrapping(): Unit = {
+ val nullEnumeration: Iterator[AnyRef] = null
+ val enumeration: ju.Iterator[AnyRef] = nullEnumeration
+
+ assert(enumeration == null)
+ }
+
+ @Test def testIterableWrapping(): Unit = {
+ val nullIterable: Iterable[AnyRef] = null
+ val iterable: jl.Iterable[AnyRef] = asJavaIterable(nullIterable)
+
+ assert(iterable == null)
+ }
+
+ @Test def testCollectionWrapping(): Unit = {
+ val nullCollection: Iterable[AnyRef] = null
+ val collection: ju.Collection[AnyRef] = nullCollection
+
+ assert(collection == null)
+ }
+
+ @Test def testBufferWrapping(): Unit = {
+ val nullList: mutable.Buffer[AnyRef] = null
+ val buffer: ju.List[AnyRef] = nullList
+
+ assert(buffer == null)
+ }
+
+ @Test def testSetWrapping(): Unit = {
+ val nullSet: mutable.Set[AnyRef] = null
+ val set: ju.Set[AnyRef] = nullSet
+
+ assert(set == null)
+ }
+
+ @Test def testMapWrapping(): Unit = {
+ val nullMap: mutable.Map[AnyRef, AnyRef] = null
+ val map: ju.Map[AnyRef, AnyRef] = nullMap
+
+ assert(map == null)
+ }
+
+ @Test def testConcurrentMapWrapping(): Unit = {
+ val nullConMap: concurrent.Map[AnyRef, AnyRef] = null
+ val conMap: juc.ConcurrentMap[AnyRef, AnyRef] = nullConMap
+
+ assert(conMap == null)
+ }
+
+ @Test def testDictionaryWrapping(): Unit = {
+ val nullDict: mutable.Map[AnyRef, AnyRef] = null
+ val dict: ju.Dictionary[AnyRef, AnyRef] = nullDict
+
+ assert(dict == null)
+ }
+
+ // Implicit conversion to ju.Properties is not available
+
+ @Test def testIteratorDecoration(): Unit = {
+ val nullIterator: Iterator[AnyRef] = null
+
+ assert(nullIterator.asJava == null)
+ }
+
+ @Test def testEnumerationDecoration(): Unit = {
+ val nullEnumeration: Iterator[AnyRef] = null
+
+ assert(nullEnumeration.asJavaEnumeration == null)
+ }
+
+ @Test def testIterableDecoration(): Unit = {
+ val nullIterable: Iterable[AnyRef] = null
+
+ assert(nullIterable.asJava == null)
+ }
+
+ @Test def testCollectionDecoration(): Unit = {
+ val nullCollection: Iterable[AnyRef] = null
+
+ assert(nullCollection.asJavaCollection == null)
+ }
+
+ @Test def testBufferDecoration(): Unit = {
+ val nullBuffer: mutable.Buffer[AnyRef] = null
+
+ assert(nullBuffer.asJava == null)
+ }
+
+ @Test def testSetDecoration(): Unit = {
+ val nullSet: Set[AnyRef] = null
+
+ assert(nullSet.asJava == null)
+ }
+
+ @Test def testMapDecoration(): Unit = {
+ val nullMap: mutable.Map[AnyRef, AnyRef] = null
+
+ assert(nullMap.asJava == null)
+ }
+
+ @Test def testConcurrentMapDecoration(): Unit = {
+ val nullConMap: concurrent.Map[AnyRef, AnyRef] = null
+
+ assert(nullConMap.asJava == null)
+ }
+
+ @Test def testDictionaryDecoration(): Unit = {
+ val nullDict: mutable.Map[AnyRef, AnyRef] = null
+
+ assert(nullDict.asJavaDictionary == null)
+ }
+
+ // Decorator conversion to ju.Properties is not available
+ }
+}
diff --git a/test/junit/scala/collection/immutable/StreamTest.scala b/test/junit/scala/collection/immutable/StreamTest.scala
new file mode 100644
index 0000000000..437cbc8926
--- /dev/null
+++ b/test/junit/scala/collection/immutable/StreamTest.scala
@@ -0,0 +1,108 @@
+package scala.collection.immutable
+
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.junit.Test
+import org.junit.Assert._
+
+import scala.ref.WeakReference
+import scala.util.Try
+
+@RunWith(classOf[JUnit4])
+class StreamTest {
+
+ @Test
+ def t6727_and_t6440(): Unit = {
+ assertTrue(Stream.continually(()).filter(_ => true).take(2) == Seq((), ()))
+ assertTrue(Stream.continually(()).filterNot(_ => false).take(2) == Seq((), ()))
+ assertTrue(Stream(1,2,3,4,5).filter(_ < 4) == Seq(1,2,3))
+ assertTrue(Stream(1,2,3,4,5).filterNot(_ > 4) == Seq(1,2,3,4))
+ }
+
+ /** Test helper to verify that the given Stream operation allows
+ * GC of the head during processing of the tail.
+ */
+ def assertStreamOpAllowsGC(op: (=> Stream[Int], Int => Unit) => Any, f: Int => Unit): Unit = {
+ val msgSuccessGC = "GC success"
+ val msgFailureGC = "GC failure"
+
+ // A stream of 500 elements at most. We will test that the head can be collected
+ // while processing the tail. After each element we will GC and wait 10 ms, so a
+ // failure to collect will take roughly 5 seconds.
+ val ref = WeakReference( Stream.from(1).take(500) )
+
+ def gcAndThrowIfCollected(n: Int): Unit = {
+ System.gc() // try to GC
+ Thread.sleep(10) // give it 10 ms
+ if (ref.get.isEmpty) throw new RuntimeException(msgSuccessGC) // we're done if head collected
+ f(n)
+ }
+
+ val res = Try { op(ref(), gcAndThrowIfCollected) }.failed // success is indicated by an
+ val msg = res.map(_.getMessage).getOrElse(msgFailureGC) // exception with expected message
+ // failure is indicated by no
+ assertTrue(msg == msgSuccessGC) // exception, or one with different message
+ }
+
+ @Test
+ def foreach_allows_GC() {
+ assertStreamOpAllowsGC(_.foreach(_), _ => ())
+ }
+
+ @Test
+ def filter_all_foreach_allows_GC() {
+ assertStreamOpAllowsGC(_.filter(_ => true).foreach(_), _ => ())
+ }
+
+ @Test // SI-8990
+ def withFilter_after_first_foreach_allows_GC: Unit = {
+ assertStreamOpAllowsGC(_.withFilter(_ > 1).foreach(_), _ => ())
+ }
+
+ @Test // SI-8990
+ def withFilter_after_first_withFilter_foreach_allows_GC: Unit = {
+ assertStreamOpAllowsGC(_.withFilter(_ > 1).withFilter(_ < 100).foreach(_), _ => ())
+ }
+
+ @Test // SI-8990
+ def withFilter_can_retry_after_exception_thrown_in_filter: Unit = {
+ // use mutable state to control an intermittent failure in filtering the Stream
+ var shouldThrow = true
+
+ val wf = Stream.from(1).take(10).withFilter { n =>
+ if (shouldThrow && n == 5) throw new RuntimeException("n == 5") else n > 5
+ }
+
+ assertTrue( Try { wf.map(identity) }.isFailure ) // throws on n == 5
+
+ shouldThrow = false // won't throw next time
+
+ assertTrue( wf.map(identity).length == 5 ) // success instead of NPE
+ }
+
+ /** Test helper to verify that the given Stream operation is properly lazy in the tail */
+ def assertStreamOpLazyInTail(op: (=> Stream[Int]) => Stream[Int], expectedEvaluated: List[Int]): Unit = {
+ // mutable state to record every strict evaluation
+ var evaluated: List[Int] = Nil
+
+ def trackEffectsOnNaturals: Stream[Int] = {
+ def loop(i: Int): Stream[Int] = { evaluated ++= List(i); i #:: loop(i + 1) }
+ loop(1)
+ }
+
+ // call op on a stream which records every strict evaluation
+ val result = op(trackEffectsOnNaturals)
+
+ assertTrue( evaluated == expectedEvaluated )
+ }
+
+ @Test // SI-9134
+ def filter_map_properly_lazy_in_tail: Unit = {
+ assertStreamOpLazyInTail(_.filter(_ % 2 == 0).map(identity), List(1, 2))
+ }
+
+ @Test // SI-9134
+ def withFilter_map_properly_lazy_in_tail: Unit = {
+ assertStreamOpLazyInTail(_.withFilter(_ % 2 == 0).map(identity), List(1, 2))
+ }
+}
diff --git a/test/junit/scala/sys/process/t7350.scala b/test/junit/scala/sys/process/t7350.scala
new file mode 100644
index 0000000000..7f3e8897f2
--- /dev/null
+++ b/test/junit/scala/sys/process/t7350.scala
@@ -0,0 +1,298 @@
+
+package scala.sys.process
+
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.junit.Test
+import java.io.{InputStream, OutputStream, PipedInputStream, PipedOutputStream, ByteArrayInputStream,
+ ByteArrayOutputStream, IOException, Closeable}
+import java.lang.reflect.InvocationTargetException
+import scala.concurrent.{Await, Future}
+import scala.concurrent.duration.{Duration, SECONDS}
+import scala.concurrent.ExecutionContext.Implicits.global
+import scala.util.control.Exception.ignoring
+
+// Each test normally ends in a moment, but for failure cases, waits until one second.
+
+@RunWith(classOf[JUnit4])
+class PipedProcessTest {
+ class ProcessMock(error: Boolean) extends Process {
+ var destroyCount = 0
+ def exitValue(): Int = {
+ if (error) {
+ throw new InterruptedException()
+ }
+ 0
+ }
+ def destroy(): Unit = { destroyCount += 1 }
+ }
+
+ class ProcessBuilderMock(process: Process, error: Boolean) extends ProcessBuilder.AbstractBuilder {
+ override def run(io: ProcessIO): Process = {
+ if (error) {
+ throw new IOException()
+ }
+ process
+ }
+ }
+
+ class PipeSinkMock extends Process.PipeSink("PipeSinkMock") {
+ var releaseCount = 0
+ override val pipe = null
+ override val sink = null
+ override def run(): Unit = {}
+ override def connectOut(out: OutputStream): Unit = {}
+ override def connectIn(pipeOut: PipedOutputStream): Unit = {}
+ override def release(): Unit = { releaseCount += 1 }
+ }
+
+ class PipeSourceMock extends Process.PipeSource("PipeSourceMock") {
+ var releaseCount = 0
+ override val pipe = null
+ override val source = null
+ override def run(): Unit = {}
+ override def connectIn(in: InputStream): Unit = {}
+ override def connectOut(sink: Process.PipeSink): Unit = {}
+ override def release(): Unit = { releaseCount += 1 }
+ }
+
+ class PipedProcesses(a: ProcessBuilder, b: ProcessBuilder, defaultIO: ProcessIO, toError: Boolean)
+ extends Process.PipedProcesses(a, b, defaultIO, toError) {
+ def callRunAndExitValue(source: Process.PipeSource, sink: Process.PipeSink) = {
+ val m = classOf[Process.PipedProcesses].getDeclaredMethod("runAndExitValue", classOf[Process.PipeSource], classOf[Process.PipeSink])
+ m.setAccessible(true)
+ try m.invoke(this, source, sink).asInstanceOf[Option[Int]]
+ catch {
+ case err: InvocationTargetException => throw err.getTargetException
+ }
+ }
+ }
+
+ // PipedProcesses need not to release resources when it normally end
+ @Test
+ def normallyEnd() {
+ val io = BasicIO(false, ProcessLogger(_ => ()))
+ val source = new PipeSourceMock
+ val sink = new PipeSinkMock
+ val a = new ProcessMock(error = false)
+ val b = new ProcessMock(error = false)
+ val p = new PipedProcesses(new ProcessBuilderMock(a, error = false), new ProcessBuilderMock(b, error = false), io, false)
+ val f = Future {
+ p.callRunAndExitValue(source, sink)
+ }
+ Await.result(f, Duration(1, SECONDS))
+ assert(source.releaseCount == 0)
+ assert(sink.releaseCount == 0)
+ assert(a.destroyCount == 0)
+ assert(b.destroyCount == 0)
+ }
+
+ // PipedProcesses must release resources when b.run() failed
+ @Test
+ def bFailed() {
+ val io = BasicIO(false, ProcessLogger(_ => ()))
+ val source = new PipeSourceMock
+ val sink = new PipeSinkMock
+ val a = new ProcessMock(error = false)
+ val b = new ProcessMock(error = false)
+ val p = new PipedProcesses(new ProcessBuilderMock(a, error = false), new ProcessBuilderMock(b, error = true), io, false)
+ val f = Future {
+ ignoring(classOf[IOException]) {
+ p.callRunAndExitValue(source, sink)
+ }
+ }
+ Await.result(f, Duration(1, SECONDS))
+ assert(source.releaseCount == 1)
+ assert(sink.releaseCount == 1)
+ assert(a.destroyCount == 0)
+ assert(b.destroyCount == 0)
+ }
+
+ // PipedProcesses must release resources when a.run() failed
+ @Test
+ def aFailed() {
+ val io = BasicIO(false, ProcessLogger(_ => ()))
+ val source = new PipeSourceMock
+ val sink = new PipeSinkMock
+ val a = new ProcessMock(error = false)
+ val b = new ProcessMock(error = false)
+ val p = new PipedProcesses(new ProcessBuilderMock(a, error = true), new ProcessBuilderMock(b, error = false), io, false)
+ val f = Future {
+ ignoring(classOf[IOException]) {
+ p.callRunAndExitValue(source, sink)
+ }
+ }
+ Await.result(f, Duration(1, SECONDS))
+ assert(source.releaseCount == 1)
+ assert(sink.releaseCount == 1)
+ assert(a.destroyCount == 0)
+ assert(b.destroyCount == 1)
+ }
+
+ // PipedProcesses must release resources when interrupted during waiting for first.exitValue()
+ @Test
+ def firstInterrupted() {
+ val io = BasicIO(false, ProcessLogger(_ => ()))
+ val source = new PipeSourceMock
+ val sink = new PipeSinkMock
+ val a = new ProcessMock(error = true)
+ val b = new ProcessMock(error = false)
+ val p = new PipedProcesses(new ProcessBuilderMock(a, error = false), new ProcessBuilderMock(b, error = false), io, false)
+ val f = Future {
+ p.callRunAndExitValue(source, sink)
+ }
+ Await.result(f, Duration(1, SECONDS))
+ assert(source.releaseCount == 1)
+ assert(sink.releaseCount == 1)
+ assert(a.destroyCount == 1)
+ assert(b.destroyCount == 1)
+ }
+
+ // PipedProcesses must release resources when interrupted during waiting for second.exitValue()
+ @Test
+ def secondInterrupted() {
+ val io = BasicIO(false, ProcessLogger(_ => ()))
+ val source = new PipeSourceMock
+ val sink = new PipeSinkMock
+ val a = new ProcessMock(error = false)
+ val b = new ProcessMock(error = true)
+ val p = new PipedProcesses(new ProcessBuilderMock(a, error = false), new ProcessBuilderMock(b, error = false), io, false)
+ val f = Future {
+ p.callRunAndExitValue(source, sink)
+ }
+ Await.result(f, Duration(1, SECONDS))
+ assert(source.releaseCount == 1)
+ assert(sink.releaseCount == 1)
+ assert(a.destroyCount == 1)
+ assert(b.destroyCount == 1)
+ }
+}
+
+@RunWith(classOf[JUnit4])
+class PipeSourceSinkTest {
+ def throwsIOException(f: => Unit) = {
+ try { f; false }
+ catch { case _: IOException => true }
+ }
+
+ class PipeSink extends Process.PipeSink("TestPipeSink") {
+ def ensureRunloopStarted() = {
+ while (sink.size() > 0) {
+ Thread.sleep(1)
+ }
+ }
+ def isReleased = {
+ val field = classOf[Process.PipeSink].getDeclaredField("pipe")
+ field.setAccessible(true)
+ val pipe = field.get(this).asInstanceOf[PipedInputStream]
+ !this.isAlive && throwsIOException { pipe.read() }
+ }
+ }
+
+ class PipeSource extends Process.PipeSource("TestPipeSource") {
+ def ensureRunloopStarted() = {
+ while (source.size() > 0) {
+ Thread.sleep(1)
+ }
+ }
+ def isReleased = {
+ val field = classOf[Process.PipeSource].getDeclaredField("pipe")
+ field.setAccessible(true)
+ val pipe = field.get(this).asInstanceOf[PipedOutputStream]
+ !this.isAlive && throwsIOException { pipe.write(1) }
+ }
+ }
+
+ trait CloseChecking extends Closeable {
+ var closed = false
+ override def close() = closed = true
+ }
+ class DebugOutputStream extends ByteArrayOutputStream with CloseChecking
+ class DebugInputStream(s: String) extends ByteArrayInputStream(s.getBytes()) with CloseChecking
+ class DebugInfinityInputStream extends InputStream with CloseChecking {
+ def read() = 1
+ }
+
+ def sourceSink() = {
+ val source = new PipeSource
+ val sink = new PipeSink
+ source connectOut sink
+ source.start()
+ sink.start()
+ (source, sink)
+ }
+
+ // PipeSource and PipeSink must release resources when it normally end
+ @Test
+ def normallyEnd() {
+ val in = new DebugInputStream("aaa")
+ val (source, sink) = sourceSink()
+ val out = new DebugOutputStream
+ source connectIn in
+ sink connectOut out
+ val f = Future {
+ source.join()
+ sink.join()
+ }
+ Await.result(f, Duration(1, SECONDS))
+ assert(in.closed == true)
+ assert(out.closed == true)
+ assert(source.isReleased == true)
+ assert(sink.isReleased == true)
+ }
+
+ // PipeSource and PipeSink must release resources when interrupted during waiting for source.take()
+ @Test
+ def sourceInterrupted() {
+ val (source, sink) = sourceSink()
+ val out = new DebugOutputStream
+ sink connectOut out
+ val f = Future {
+ sink.ensureRunloopStarted()
+ source.release()
+ sink.release()
+ }
+ Await.result(f, Duration(1, SECONDS))
+ assert(out.closed == true)
+ assert(source.isReleased == true)
+ assert(sink.isReleased == true)
+ }
+
+ // PipeSource and PipeSink must release resources when interrupted during waiting for sink.take()
+ @Test
+ def sinkInterrupted() {
+ val in = new DebugInputStream("aaa")
+ val (source, sink) = sourceSink()
+ source connectIn in
+ val f = Future {
+ source.ensureRunloopStarted()
+ source.release()
+ sink.release()
+ }
+ Await.result(f, Duration(1, SECONDS))
+ assert(in.closed == true)
+ assert(source.isReleased == true)
+ assert(sink.isReleased == true)
+ }
+
+ // PipeSource and PipeSink must release resources when interrupted during copy streams"
+ @Test
+ def runloopInterrupted() {
+ val in = new DebugInfinityInputStream
+ val (source, sink) = sourceSink()
+ val out = new DebugOutputStream
+ source connectIn in
+ sink connectOut out
+ val f = Future {
+ source.ensureRunloopStarted()
+ sink.ensureRunloopStarted()
+ source.release()
+ sink.release()
+ }
+ Await.result(f, Duration(1, SECONDS))
+ assert(in.closed == true)
+ assert(out.closed == true)
+ assert(source.isReleased == true)
+ assert(sink.isReleased == true)
+ }
+}
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/CompactLocalVariablesTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/CompactLocalVariablesTest.scala
index 76492cfa23..cd298f822a 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/CompactLocalVariablesTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/CompactLocalVariablesTest.scala
@@ -17,8 +17,8 @@ class CompactLocalVariablesTest {
// recurse-unreachable-jumps is required for eliminating catch blocks, in the first dce round they
// are still live.only after eliminating the empty handler the catch blocks become unreachable.
- val methodOptCompiler = newCompiler(extraArgs = "-target:jvm-1.6 -Ybackend:GenBCode -Yopt:unreachable-code,compact-locals")
- val noCompactVarsCompiler = newCompiler(extraArgs = "-target:jvm-1.6 -Ybackend:GenBCode -Yopt:unreachable-code")
+ val methodOptCompiler = newCompiler(extraArgs = "-Ybackend:GenBCode -Yopt:unreachable-code,compact-locals")
+ val noCompactVarsCompiler = newCompiler(extraArgs = "-Ybackend:GenBCode -Yopt:unreachable-code")
@Test
def compactUnused(): Unit = {
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOpts.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOpts.scala
index 5ef2458c0a..8d910629ca 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOpts.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOpts.scala
@@ -16,7 +16,7 @@ import ASMConverters._
import scala.tools.testing.ClearAfterClass
object MethodLevelOpts extends ClearAfterClass.Clearable {
- var methodOptCompiler = newCompiler(extraArgs = "-target:jvm-1.6 -Ybackend:GenBCode -Yopt:l:method")
+ var methodOptCompiler = newCompiler(extraArgs = "-Ybackend:GenBCode -Yopt:l:method")
def clear(): Unit = { methodOptCompiler = null }
}
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala
index 902af7b7fa..0ac206669a 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala
@@ -18,18 +18,14 @@ import scala.tools.testing.ClearAfterClass
object UnreachableCodeTest extends ClearAfterClass.Clearable {
// jvm-1.6 enables emitting stack map frames, which impacts the code generation wrt dead basic blocks,
// see comment in BCodeBodyBuilder
- var methodOptCompiler = newCompiler(extraArgs = "-target:jvm-1.6 -Ybackend:GenBCode -Yopt:l:method")
- var dceCompiler = newCompiler(extraArgs = "-target:jvm-1.6 -Ybackend:GenBCode -Yopt:unreachable-code")
- var noOptCompiler = newCompiler(extraArgs = "-target:jvm-1.6 -Ybackend:GenBCode -Yopt:l:none")
-
- // jvm-1.5 disables computing stack map frames, and it emits dead code as-is. note that this flag triggers a deprecation warning
- var noOptNoFramesCompiler = newCompiler(extraArgs = "-target:jvm-1.5 -Ybackend:GenBCode -Yopt:l:none -deprecation")
+ var methodOptCompiler = newCompiler(extraArgs = "-Ybackend:GenBCode -Yopt:l:method")
+ var dceCompiler = newCompiler(extraArgs = "-Ybackend:GenBCode -Yopt:unreachable-code")
+ var noOptCompiler = newCompiler(extraArgs = "-Ybackend:GenBCode -Yopt:l:none")
def clear(): Unit = {
methodOptCompiler = null
dceCompiler = null
noOptCompiler = null
- noOptNoFramesCompiler = null
}
}
@@ -40,7 +36,6 @@ class UnreachableCodeTest extends ClearAfterClass {
val methodOptCompiler = UnreachableCodeTest.methodOptCompiler
val dceCompiler = UnreachableCodeTest.dceCompiler
val noOptCompiler = UnreachableCodeTest.noOptCompiler
- val noOptNoFramesCompiler = UnreachableCodeTest.noOptNoFramesCompiler
def assertEliminateDead(code: (Instruction, Boolean)*): Unit = {
val method = genMethod()(code.map(_._1): _*)
@@ -152,11 +147,6 @@ class UnreachableCodeTest extends ClearAfterClass {
// Finally, instructions in the dead basic blocks are replaced by ATHROW, as explained in
// a comment in BCodeBodyBuilder.
assertSameCode(noDce.dropNonOp, List(Op(ICONST_1), Op(IRETURN), Op(ATHROW), Op(ATHROW)))
-
- // when NOT computing stack map frames, ASM's ClassWriter does not replace dead code by NOP/ATHROW
- val warn = "target:jvm-1.5 is deprecated"
- val noDceNoFrames = singleMethodInstructions(noOptNoFramesCompiler)(code, allowMessage = _.msg contains warn)
- assertSameCode(noDceNoFrames.dropNonOp, List(Op(ICONST_1), Op(IRETURN), Op(ICONST_2), Op(IRETURN)))
}
@Test
diff --git a/test/junit/scala/tools/nsc/settings/ScalaVersionTest.scala b/test/junit/scala/tools/nsc/settings/ScalaVersionTest.scala
index 77a2da828e..acbf39fe23 100644
--- a/test/junit/scala/tools/nsc/settings/ScalaVersionTest.scala
+++ b/test/junit/scala/tools/nsc/settings/ScalaVersionTest.scala
@@ -13,6 +13,48 @@ class ScalaVersionTest {
@Test def versionUnparse() {
val v = "2.11.3"
- assertEquals(ScalaVersion(v).unparse, v)
+ assertEquals(v, ScalaVersion(v).unparse)
+ assertEquals("2.11.3-RC4", ScalaVersion("2.11.3-rc4").unparse)
+ }
+
+ // SI-9167
+ @Test def `version parses with rigor`() {
+ import settings.{ SpecificScalaVersion => V }
+ import ScalaVersion._
+
+ // no-brainers
+ assertEquals(V(2,11,7,Final), ScalaVersion("2.11.7"))
+ assertEquals(V(2,11,7,Final), ScalaVersion("2.11.7-FINAL"))
+ assertEquals(V(2,11,7,Milestone(3)), ScalaVersion("2.11.7-M3"))
+ assertEquals(V(2,11,7,RC(3)), ScalaVersion("2.11.7-RC3"))
+ assertEquals(V(2,11,7,Development("devbuild")), ScalaVersion("2.11.7-devbuild"))
+
+ // partial-brainers
+ assertEquals(V(2,11,7,Milestone(3)), ScalaVersion("2.11.7-m3"))
+ assertEquals(V(2,11,7,RC(3)), ScalaVersion("2.11.7-rc3"))
+ assertEquals(V(2,11,7,Development("maybegood")), ScalaVersion("2.11.7-maybegood"))
+ assertEquals(V(2,11,7,Development("RCCola")), ScalaVersion("2.11.7-RCCola"))
+ assertEquals(V(2,11,7,Development("RC1.5")), ScalaVersion("2.11.7-RC1.5"))
+ assertEquals(V(2,11,7,Development("")), ScalaVersion("2.11.7-"))
+ assertEquals(V(2,11,7,Development("0.5")), ScalaVersion("2.11.7-0.5"))
+ assertEquals(V(2,11,7,Development("devbuild\nSI-9167")), ScalaVersion("2.11.7-devbuild\nSI-9167"))
+ assertEquals(V(2,11,7,Development("final")), ScalaVersion("2.11.7-final"))
+
+ // oh really
+ assertEquals(NoScalaVersion, ScalaVersion("none"))
+ assertEquals(AnyScalaVersion, ScalaVersion("any"))
+
+ assertThrows[NumberFormatException] { ScalaVersion("2.11.7.2") }
+ assertThrows[NumberFormatException] { ScalaVersion("2.11.7.beta") }
+ assertThrows[NumberFormatException] { ScalaVersion("2.x.7") }
+ assertThrows[NumberFormatException] { ScalaVersion("2.-11.7") }
+ assertThrows[NumberFormatException] { ScalaVersion("2. ") }
+ assertThrows[NumberFormatException] { ScalaVersion("2.1 .7") }
+ assertThrows[NumberFormatException] { ScalaVersion("2.") }
+ assertThrows[NumberFormatException] { ScalaVersion("2..") }
+ assertThrows[NumberFormatException] { ScalaVersion("2...") }
+ assertThrows[NumberFormatException] { ScalaVersion("2-") }
+ assertThrows[NumberFormatException] { ScalaVersion("2-.") } // scalacheck territory
+ assertThrows[NumberFormatException] { ScalaVersion("any.7") }
}
}
diff --git a/test/long-running/jvm/memleak2_actor.scala b/test/long-running/jvm/memleak2_actor.scala
deleted file mode 100644
index 1673b12dac..0000000000
--- a/test/long-running/jvm/memleak2_actor.scala
+++ /dev/null
@@ -1,39 +0,0 @@
-import scala.actors._
-import Actor._
-
-case object Start
-case object EndMe
-
-class A extends Actor {
- def act = loop {
- react {
- case Start =>
- case EndMe =>
- exit()
- }
- }
-}
-
-object Test {
-
- def z(in: Long) = if (in / 1024L == 0L) in
- else if (in / (1024L * 1024L) == 0L) (in / 1024L).toString + "K"
- else (in / (1024L * 1024L)).toString + "M"
-
- def main(args: Array[String]) {
- val rt = Runtime.getRuntime()
- for (o <- 1 to 300000) {
- println("Outer [2AN] "+o)
- var a: List[A] = Nil
- for (i <- 1 to 10000) {
- var t = new A
- a = t :: a
- t.start
- t ! Start
- }
- for (act <- a) act ! EndMe
- //rt.gc()
- println("Free "+z(rt.freeMemory())+" total "+z(rt.totalMemory()))
- }
- }
-}
diff --git a/test/pending/jvm/actor-executor4.check b/test/pending/jvm/actor-executor4.check
deleted file mode 100644
index da78f45836..0000000000
--- a/test/pending/jvm/actor-executor4.check
+++ /dev/null
@@ -1,21 +0,0 @@
-Two: OK
-One: OK
-Two: OK
-One: OK
-Two: OK
-One: OK
-Two: OK
-One: OK
-Two: OK
-One: OK
-Two: OK
-One: OK
-Two: OK
-One: OK
-Two: OK
-One: OK
-Two: OK
-One: OK
-Two: OK
-One: OK
-One exited
diff --git a/test/pending/jvm/actor-executor4.scala b/test/pending/jvm/actor-executor4.scala
deleted file mode 100644
index a912d76094..0000000000
--- a/test/pending/jvm/actor-executor4.scala
+++ /dev/null
@@ -1,64 +0,0 @@
-import scala.actors.{Actor, Exit}
-import scala.actors.scheduler.ExecutorScheduler
-import java.util.concurrent.Executors
-
-object One extends AdaptedActor {
- def act() {
- Two.start()
- var i = 0
- loopWhile (i < Test.NUM_MSG) {
- i += 1
- Two ! 'MsgForTwo
- react {
- case 'MsgForOne =>
- if (i % (Test.NUM_MSG/10) == 0)
- println("One: OK")
- }
- }
- }
-}
-
-object Two extends AdaptedActor {
- def act() {
- var i = 0
- loopWhile (i < Test.NUM_MSG) {
- i += 1
- react {
- case 'MsgForTwo =>
- if (i % (Test.NUM_MSG/10) == 0)
- println("Two: OK")
- One ! 'MsgForOne
- }
- }
- }
-}
-
-trait AdaptedActor extends Actor {
- override def scheduler =
- Test.scheduler
-}
-
-object Test {
- val NUM_MSG = 100000
-
- val scheduler =
- ExecutorScheduler(
- Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()),
- false)
-
- def main(args: Array[String]) {
- (new AdaptedActor {
- def act() {
- trapExit = true
- link(One)
- One.start()
-
- receive {
- case Exit(from, reason) =>
- println("One exited")
- Test.scheduler.shutdown()
- }
- }
- }).start()
- }
-}
diff --git a/test/pending/jvm/actor-receive-sender.check b/test/pending/jvm/actor-receive-sender.check
deleted file mode 100644
index 2c94e48371..0000000000
--- a/test/pending/jvm/actor-receive-sender.check
+++ /dev/null
@@ -1,2 +0,0 @@
-OK
-OK
diff --git a/test/pending/jvm/actor-receive-sender.scala b/test/pending/jvm/actor-receive-sender.scala
deleted file mode 100644
index ea7c40cced..0000000000
--- a/test/pending/jvm/actor-receive-sender.scala
+++ /dev/null
@@ -1,51 +0,0 @@
-import scala.actors.{Actor, TIMEOUT, Exit}
-import scala.actors.Actor._
-
-object Test {
-
- val NUM = 2000
-
- def main(args: Array[String]) {
- var b: Actor = null
- var c: Actor = null
-
- val a = actor {
- for (_ <- 0 until NUM)
- receive {
- case 'hello if sender == b => // do nothing
- }
- b ! 'ok
- for (_ <- 0 until NUM)
- receiveWithin (1000) {
- case 'bye if sender == b => // do nothing
- case TIMEOUT => b ! 'fail
- }
- b ! 'ok
- }
-
- b = actor {
- self.trapExit = true
- link(a)
-
- for (_ <- 0 until NUM)
- a ! 'hello
-
- val proceed = receive {
- case Exit(from, reason) => println("FAIL"); false
- case 'ok => println("OK"); true
- case other => println(other); false
- }
-
- if (proceed) {
- for (_ <- 0 until NUM)
- a ! 'bye
- receive {
- case Exit(from, reason) => println("FAIL")
- case 'ok => println("OK")
- case other => println(other)
- }
- }
- }
- }
-
-}
diff --git a/test/pending/jvm/actorgc_leak.check b/test/pending/jvm/actorgc_leak.check
deleted file mode 100644
index a965a70ed4..0000000000
--- a/test/pending/jvm/actorgc_leak.check
+++ /dev/null
@@ -1 +0,0 @@
-Done
diff --git a/test/pending/jvm/actorgc_leak.scala b/test/pending/jvm/actorgc_leak.scala
deleted file mode 100644
index de3e04f1e8..0000000000
--- a/test/pending/jvm/actorgc_leak.scala
+++ /dev/null
@@ -1,63 +0,0 @@
-
-import scala.actors.Actor
-
-object Test {
- class FatActorFactory extends Actor {
- def act() {
- var cnt = 0
- Actor.loopWhile(cnt < fatActors) {
- //if ((cnt % 5) == 0) println(cnt)
- val fa = new FatActor()
- fa.start()
- cnt += 1
- if (cnt == fatActors) Monitor ! 'done
- }
- }
- }
-
- class FatActor extends Actor {
- def act() {
- fat = new Array[Int](fatness)
- react {
- case 'hi => exit()
- }
- }
- private var fat: Array[Int] = _
- }
-
- object Monitor extends Actor {
- private var cnt = 0
- def act() {
- Actor.loop {
- react {
- case 'done => {
- cnt += 1
- if (cnt == factories) System.exit(0) // once GC pressure stops FatActors stop being collected, and as
- } // a result ActorGC never finds out that they are defunct
- }
- }
- }
- }
-
- val factories = 4 // the number of factories to start
- val fatActors = 50 // the number of FatActors for each factory to produce
- val fatness = 1024*1024*10
-
- def main(args: Array[String]) {
- scala.actors.Scheduler.impl.shutdown()
- val sched = {
- val s = new scala.actors.FJTaskScheduler2
- s.start()
- s
- }
- scala.actors.Scheduler.impl = sched
-
- Monitor.start()
- for(i <- 1 to factories) {
- //if ((i % 50) == 0) println(i)
- val fa = new FatActorFactory()
- fa.start()
- }
- println("Done")
- }
-}
diff --git a/test/pending/jvm/reactWithinZero.check b/test/pending/jvm/reactWithinZero.check
deleted file mode 100644
index cf2a2facf9..0000000000
--- a/test/pending/jvm/reactWithinZero.check
+++ /dev/null
@@ -1,2 +0,0 @@
-TIMEOUT
-'ack
diff --git a/test/pending/jvm/reactWithinZero.scala b/test/pending/jvm/reactWithinZero.scala
deleted file mode 100644
index 0786ce271d..0000000000
--- a/test/pending/jvm/reactWithinZero.scala
+++ /dev/null
@@ -1,18 +0,0 @@
-import scala.actors.{Actor, TIMEOUT}
-
-class A extends Actor {
- def act() = reactWithin(0) {
- case TIMEOUT =>
- println("TIMEOUT")
- reply('ack)
- act()
- case x => println(x)
- }
-}
-
-object Test {
- def main(args: Array[String]): Unit = {
- val a = new A
- a.start()
- }
-}
diff --git a/test/pending/jvm/receiveWithinZero.check b/test/pending/jvm/receiveWithinZero.check
deleted file mode 100644
index cf2a2facf9..0000000000
--- a/test/pending/jvm/receiveWithinZero.check
+++ /dev/null
@@ -1,2 +0,0 @@
-TIMEOUT
-'ack
diff --git a/test/pending/jvm/receiveWithinZero.scala b/test/pending/jvm/receiveWithinZero.scala
deleted file mode 100644
index 315dd9c86a..0000000000
--- a/test/pending/jvm/receiveWithinZero.scala
+++ /dev/null
@@ -1,18 +0,0 @@
-import scala.actors.{Actor, TIMEOUT}
-
-class A extends Actor {
- def act() = receiveWithin(0) {
- case TIMEOUT =>
- println("TIMEOUT")
- reply('ack)
- act()
- case x => println(x)
- }
-}
-
-object Test {
- def main(args: Array[String]): Unit = {
- val a = new A
- a.start()
- }
-}
diff --git a/test/pending/jvm/t1801.check b/test/pending/jvm/t1801.check
deleted file mode 100644
index bf78a99db9..0000000000
--- a/test/pending/jvm/t1801.check
+++ /dev/null
@@ -1,6 +0,0 @@
-0
-100
-200
-300
-400
-done!
diff --git a/test/pending/jvm/t1801.scala b/test/pending/jvm/t1801.scala
deleted file mode 100644
index 6ed7c56336..0000000000
--- a/test/pending/jvm/t1801.scala
+++ /dev/null
@@ -1,31 +0,0 @@
-import scala.actors.Actor._
-
-object Test {
- val rt = Runtime.getRuntime()
- val sender = actor {
- var cnt = 0
- while(cnt < 500) {
- if ((cnt % 100) == 0) println(cnt)
- receiver ! new Array[Int] (148576)
- cnt += 1
- //println ("Used Mem: " + (((rt.totalMemory() - rt.freeMemory()) / 1048576.) formatted "%.2f") + " Mb")
- }
- receiver ! 'exit
- }
-
- val receiver = actor {
- loop {
- react {
- case x: Array[Int] => ()//println ("received " + x.length)
- case 'exit => {
- println("done!")
- exit()
- }
- }
- }
- }
-
- def main (args: Array[String]) {
- sender
- }
-}
diff --git a/test/pending/jvm/t2515.check b/test/pending/jvm/t2515.check
deleted file mode 100644
index 8cb8bde11e..0000000000
--- a/test/pending/jvm/t2515.check
+++ /dev/null
@@ -1,10 +0,0 @@
-Iteration 1 succeeded
-Iteration 2 succeeded
-Iteration 3 succeeded
-Iteration 4 succeeded
-Iteration 5 succeeded
-Iteration 6 succeeded
-Iteration 7 succeeded
-Iteration 8 succeeded
-Iteration 9 succeeded
-Iteration 10 succeeded
diff --git a/test/pending/jvm/t2515.scala b/test/pending/jvm/t2515.scala
deleted file mode 100644
index ee655967f3..0000000000
--- a/test/pending/jvm/t2515.scala
+++ /dev/null
@@ -1,43 +0,0 @@
-import scala.actors.{Futures, TIMEOUT}
-import scala.actors.Actor._
-
-object Test {
-
- def compute(): Option[Boolean] = {
- val fts = for (j <- 0 until 5) yield Futures.future {
- receiveWithin (100) {
- case TIMEOUT => true
- case other => false
- }
- }
- val done = Futures.awaitAll(2000, fts.toArray: _*) // list to array, as varargs
- if (done.contains(None))
- None
- else
- Some(true)
- }
-
- def main(args:Array[String]) : Unit = {
- val ft = Futures.future {
- val format = new java.text.DecimalFormat("000.00'ms'")
- var iter = 1
- val done = 11
- while (iter < done) {
- val start = System.nanoTime()
- val result = compute()
- val time = System.nanoTime() - start
- result match {
- case Some(result) =>
- //printf("Iteration %2d succeeded after %s %n", iter, format.format(time / 1e6))
- printf("Iteration %2d succeeded%n", iter)
- iter += 1
- case None =>
- printf(">>>> Iteration %2d failed after %s <<<<< %n", iter, format.format(time / 1e6))
- iter = done
- }
- }
- }
- ft()
- }
-
-}
diff --git a/test/pending/jvm/terminateLinked.check b/test/pending/jvm/terminateLinked.check
deleted file mode 100644
index a965a70ed4..0000000000
--- a/test/pending/jvm/terminateLinked.check
+++ /dev/null
@@ -1 +0,0 @@
-Done
diff --git a/test/pending/jvm/terminateLinked.scala b/test/pending/jvm/terminateLinked.scala
deleted file mode 100644
index 2a3b7fb49e..0000000000
--- a/test/pending/jvm/terminateLinked.scala
+++ /dev/null
@@ -1,24 +0,0 @@
-import scala.actors.Actor
-import Actor._
-
-object Test {
- def main(args: Array[String]) {
- val a = actor {
- for (_ <- 1 to 10)
- receive {
- case b: Actor => link(b)
- }
- throw new Exception
- }
-
- for (_ <- 1 to 10)
- actor {
- a ! self
- react {
- case _ =>
- }
- }
-
- println("Done")
- }
-}
diff --git a/test/pending/jvm/timeout.check b/test/pending/jvm/timeout.check
deleted file mode 100644
index d86bac9de5..0000000000
--- a/test/pending/jvm/timeout.check
+++ /dev/null
@@ -1 +0,0 @@
-OK
diff --git a/test/pending/jvm/timeout.scala b/test/pending/jvm/timeout.scala
deleted file mode 100644
index 8f29f8ddbe..0000000000
--- a/test/pending/jvm/timeout.scala
+++ /dev/null
@@ -1,38 +0,0 @@
-// Test is in pending because although it succeeds locally,
-// it takes too long on the machine which runs nightly tests.
-//
-// [partest] EXPECTED: 100 < x < 900
-// [partest] ACTUAL: 1519
-
-import scala.actors.Actor._
-import scala.actors.TIMEOUT
-
-object Test extends Application {
- case class Timing(time: Long)
-
- actor {
- val a = actor {
- react {
- case 'doTiming =>
- val s = sender
- reactWithin(500) {
- case TIMEOUT =>
- s ! Timing(System.currentTimeMillis)
- }
- }
- }
-
- val start = System.currentTimeMillis
- (a !? 'doTiming) match {
- case Timing(end) =>
- val delay = end - start
-
- if (delay > 100 && delay < 900)
- println("OK")
- else {
- println("EXPECTED: 100 < x < 900")
- println("ACTUAL: "+delay)
- }
- }
- }
-}
diff --git a/test/pending/run/t5698/client.scala b/test/pending/run/t5698/client.scala
deleted file mode 100644
index de672c1809..0000000000
--- a/test/pending/run/t5698/client.scala
+++ /dev/null
@@ -1,9 +0,0 @@
-package client
-
-
-
-object Client extends App {
- val peer = actors.remote.Node("localhost", 23456)
- val a = actors.remote.RemoteActor.select(peer, 'test)
- a ! server.TestMsg
-}
diff --git a/test/pending/run/t5698/server.scala b/test/pending/run/t5698/server.scala
deleted file mode 100644
index e8f3cea225..0000000000
--- a/test/pending/run/t5698/server.scala
+++ /dev/null
@@ -1,22 +0,0 @@
-package server
-
-
-
-object Server extends App {
-
- class ServerActor extends actors.Actor {
- def act() {
- actors.remote.RemoteActor.alive(23456)
- actors.remote.RemoteActor.register('test, actors.Actor.self)
- loop {
- react {
- case TestMsg => println("Yay!")
- }
- }
- }
- }
-
- val a = new ServerActor
- a.start()
-
-}
diff --git a/test/pending/run/t5698/testmsg.scala b/test/pending/run/t5698/testmsg.scala
deleted file mode 100644
index 004ff0b8c7..0000000000
--- a/test/pending/run/t5698/testmsg.scala
+++ /dev/null
@@ -1,5 +0,0 @@
-package server
-
-
-
-case object TestMsg
diff --git a/test/scaladoc/filters b/test/scaladoc/filters
index 51a7507848..e91ca0eb36 100644
--- a/test/scaladoc/filters
+++ b/test/scaladoc/filters
@@ -1,6 +1,7 @@
#
#Java HotSpot(TM) 64-Bit Server VM warning: Failed to reserve shared memory (errno = 28).
Java HotSpot\(TM\) .* warning:
+OpenJDK .* warning:
# Hotspot receiving VM options through the $_JAVA_OPTIONS
# env variable outputs them on stderr
Picked up _JAVA_OPTIONS:
diff --git a/test/scaladoc/run/t7905.check b/test/scaladoc/run/t7905.check
new file mode 100644
index 0000000000..619c56180b
--- /dev/null
+++ b/test/scaladoc/run/t7905.check
@@ -0,0 +1 @@
+Done.
diff --git a/test/scaladoc/run/t7905.scala b/test/scaladoc/run/t7905.scala
new file mode 100644
index 0000000000..8570724470
--- /dev/null
+++ b/test/scaladoc/run/t7905.scala
@@ -0,0 +1,36 @@
+import scala.tools.nsc.doc.model._
+import scala.tools.partest.ScaladocModelTest
+
+object Test extends ScaladocModelTest {
+ override def code = """
+ object A {
+ val foo = new B {
+ val bar = new C {
+ val baz: A.this.type = A.this
+ }
+ }
+ }
+
+ trait B {
+ type E = bar.D
+
+ val bar: C
+ }
+
+ trait C {
+ trait D
+ }
+
+ trait G {
+ type F = A.foo.E
+
+ def m(f: F) = f match {
+ case _: A.foo.bar.D => // error here
+ }
+ }
+ """
+
+ def scaladocSettings = ""
+
+ def testModel(root: Package) = ()
+}
diff --git a/test/scaladoc/scalacheck/HtmlFactoryTest.scala b/test/scaladoc/scalacheck/HtmlFactoryTest.scala
index 578e0382eb..913667b79b 100644
--- a/test/scaladoc/scalacheck/HtmlFactoryTest.scala
+++ b/test/scaladoc/scalacheck/HtmlFactoryTest.scala
@@ -779,6 +779,11 @@ object Test extends Properties("HtmlFactory") {
linkElement \@ "href" == expectedUrl && linkElement \@ "target" == "_top"
}
+ def assertValuesLink(memberName: String, expectedUrl: String): Boolean = {
+ val linkElement: NodeSeq = node \\ "div" \@ ("class", "values members") \\ "li" \@ ("name", memberName) \\ "span" \@ ("class", "permalink") \ "a"
+ linkElement \@ "href" == expectedUrl && linkElement \@ "target" == "_top"
+ }
+
}
val files = createTemplates("SI-8144.scala")
@@ -791,12 +796,12 @@ object Test extends Properties("HtmlFactory") {
property("SI-8144: Members' permalink - package") = check("some/package.html") { node =>
("type link" |: node.assertTypeLink("../index.html#some.package")) &&
- ("member: some.pack" |: node.assertMemberLink("values")("some.pack", "../index.html#some.package@pack"))
+ ("member: some.pack" |: node.assertValuesLink("some.pack", "../index.html#some.package@pack"))
}
property("SI-8144: Members' permalink - inner package") = check("some/pack/package.html") { node =>
("type link" |: node.assertTypeLink("../../index.html#some.pack.package")) &&
- ("member: SomeType (object)" |: node.assertMemberLink("values")("some.pack.SomeType", "../../index.html#some.pack.package@SomeType")) &&
+ ("member: SomeType (object)" |: node.assertValuesLink("some.pack.SomeType", "../../index.html#some.pack.package@SomeType")) &&
("member: SomeType (class)" |: node.assertMemberLink("types")("some.pack.SomeType", "../../index.html#some.pack.package@SomeTypeextendsAnyRef"))
}
@@ -809,8 +814,8 @@ object Test extends Properties("HtmlFactory") {
("type link" |: node.assertTypeLink("../../index.html#some.pack.SomeType")) &&
("constructor " |: node.assertMemberLink("constructors")("some.pack.SomeType#<init>", "../../index.html#some.pack.SomeType@<init>(arg:String):some.pack.SomeType")) &&
( "member: type TypeAlias" |: node.assertMemberLink("types")("some.pack.SomeType.TypeAlias", "../../index.html#some.pack.SomeType@TypeAlias=String")) &&
- ( "member: def >#<():Int " |: node.assertMemberLink("values")("some.pack.SomeType#>#<", "../../index.html#some.pack.SomeType@>#<():Int")) &&
- ( "member: def >@<():TypeAlias " |: node.assertMemberLink("values")("some.pack.SomeType#>@<", "../../index.html#some.pack.SomeType@>@<():SomeType.this.TypeAlias"))
+ ( "member: def >#<():Int " |: node.assertValuesLink("some.pack.SomeType#>#<", "../../index.html#some.pack.SomeType@>#<():Int")) &&
+ ( "member: def >@<():TypeAlias " |: node.assertValuesLink("some.pack.SomeType#>@<", "../../index.html#some.pack.SomeType@>@<():SomeType.this.TypeAlias"))
}
}
diff --git a/versions.properties b/versions.properties
index a7ec8caedc..470c9341cd 100644
--- a/versions.properties
+++ b/versions.properties
@@ -1,4 +1,4 @@
-#Wed, 23 Jul 2014 08:37:26 +0200
+#Fri, 01 May 2015 16:27:16 +0000
# NOTE: this file determines the content of the scala-distribution
# via scala-dist-pom.xml and scala-library-all-pom.xml
# when adding new properties that influence a release,
@@ -8,7 +8,7 @@
# The scala version used for boostrapping. This has no impact on the final classfiles:
# there are two stages (locker and quick), so compiler and library are always built
# with themselves. Stability is ensured by building a third stage (strap).
-starr.version=2.11.6
+starr.version=2.12.0-M1
# These are the versions of the modules that go with this release.
# These properties are used during PR validation and in dbuild builds.
@@ -19,19 +19,12 @@ starr.version=2.11.6
# - After 2.x.0 is released, the binary version is 2.x.
# - During milestones and RCs, modules are cross-built against the full version.
# So the value is the full version (e.g. 2.12.0-M1).
-scala.binary.version=2.11
-# e.g. 2.11.0-RC1, 2.11.0, 2.11.1-RC1, 2.11.1
-# this defines the dependency on scala-continuations-plugin in scala-dist's pom
-scala.full.version=2.11.6
+scala.binary.version=2.12.0-M1
# external modules shipped with distribution, as specified by scala-library-all's pom
scala-xml.version.number=1.0.4
scala-parser-combinators.version.number=1.0.4
-scala-continuations-plugin.version.number=1.0.2
-scala-continuations-library.version.number=1.0.2
scala-swing.version.number=1.0.2
-akka-actor.version.number=2.3.10
-actors-migration.version.number=1.1.0
jline.version=2.12.1
scala-asm.version=5.0.4-scala-1