EMMA Coverage Report (generated Wed Oct 26 13:47:17 EDT 2011)
[all classes][org.jclouds.concurrent]

COVERAGE SUMMARY FOR SOURCE FILE [MoreExecutors.java]

nameclass, %method, %block, %line, %
MoreExecutors.java67%  (2/3)67%  (8/12)47%  (93/199)57%  (28.5/50)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class MoreExecutors$10%   (0/1)100% (0/0)100% (0/0)100% (0/0)
     
class MoreExecutors$SameThreadExecutorService100% (1/1)70%  (7/10)46%  (88/191)58%  (27.5/47)
awaitTermination (long, TimeUnit): boolean 0%   (0/1)0%   (0/40)0%   (0/8)
shutdown (): void 0%   (0/1)0%   (0/17)0%   (0/5)
shutdownNow (): List 0%   (0/1)0%   (0/4)0%   (0/2)
isTerminated (): boolean 100% (1/1)54%  (13/24)74%  (2.2/3)
startTask (): void 100% (1/1)61%  (17/28)80%  (5.6/7)
execute (Runnable): void 100% (1/1)62%  (8/13)92%  (4.6/5)
isShutdown (): boolean 100% (1/1)65%  (11/17)88%  (2.6/3)
endTask (): void 100% (1/1)65%  (17/26)77%  (5.4/7)
MoreExecutors$SameThreadExecutorService (): void 100% (1/1)100% (19/19)100% (6/6)
MoreExecutors$SameThreadExecutorService (MoreExecutors$1): void 100% (1/1)100% (3/3)100% (1/1)
     
class MoreExecutors100% (1/1)50%  (1/2)62%  (5/8)33%  (1/3)
MoreExecutors (): void 0%   (0/1)0%   (0/3)0%   (0/2)
sameThreadExecutor (): ExecutorService 100% (1/1)100% (5/5)100% (1/1)

1/**
2 * Licensed to jclouds, Inc. (jclouds) under one or more
3 * contributor license agreements.  See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership.  jclouds licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License.  You may obtain a copy of the License at
9 *
10 *   http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied.  See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19/*
20 * Copyright (C) 2007 Google Inc.
21 *
22 * Licensed under the Apache License, Version 2.0 (the "License");
23 * you may not use this file except in compliance with the License.
24 * You may obtain a copy of the License at
25 *
26 * http://www.apache.org/licenses/LICENSE-2.0
27 *
28 * Unless required by applicable law or agreed to in writing, software
29 * distributed under the License is distributed on an "AS IS" BASIS,
30 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31 * See the License for the specific language governing permissions and
32 * limitations under the License.
33 */
34 
35package org.jclouds.concurrent;
36 
37import java.util.Collections;
38import java.util.List;
39import java.util.concurrent.AbstractExecutorService;
40import java.util.concurrent.ExecutorService;
41import java.util.concurrent.RejectedExecutionException;
42import java.util.concurrent.TimeUnit;
43import java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy;
44import java.util.concurrent.locks.Condition;
45import java.util.concurrent.locks.Lock;
46import java.util.concurrent.locks.ReentrantLock;
47 
48import com.google.common.annotations.Beta;
49 
50/**
51 * functions related to or replacing those in
52 * {@link com.google.common.util.concurrent.MoreExecutors}
53 * 
54 * @author Adrian Cole
55 */
56@Beta
57public class MoreExecutors {
58 
59   /**
60    * Taken from @link com.google.common.util.concurrent.MoreExecutors} as it was hidden and
61    * therefore incapable of instanceof checks.
62    * 
63    * 
64    * Creates an executor service that runs each task in the thread that invokes {@code
65    * execute/submit}, as in {@link CallerRunsPolicy} This applies both to individually submitted
66    * tasks and to collections of tasks submitted via {@code invokeAll} or {@code invokeAny}. In the
67    * latter case, tasks will run serially on the calling thread. Tasks are run to completion before
68    * a {@code Future} is returned to the caller (unless the executor has been shutdown).
69    * 
70    * <p>
71    * Although all tasks are immediately executed in the thread that submitted the task, this
72    * {@code ExecutorService} imposes a small locking overhead on each task submission in order to
73    * implement shutdown and termination behavior.
74    * 
75    * <p>
76    * The implementation deviates from the {@code ExecutorService} specification with regards to the
77    * {@code shutdownNow} method. First, "best-effort" with regards to canceling running tasks is
78    * implemented as "no-effort". No interrupts or other attempts are made to stop threads executing
79    * tasks. Second, the returned list will always be empty, as any submitted task is considered to
80    * have started execution. This applies also to tasks given to {@code invokeAll} or {@code
81    * invokeAny} which are pending serial execution, even the subset of the tasks that have not yet
82    * started execution. It is unclear from the {@code ExecutorService} specification if these
83    * should be included, and it's much easier to implement the interpretation that they not be.
84    * Finally, a call to {@code shutdown} or {@code shutdownNow} may result in concurrent calls to
85    * {@code invokeAll/invokeAny} throwing RejectedExecutionException, although a subset of the
86    * tasks may already have been executed.
87    */
88   public static ExecutorService sameThreadExecutor() {
89      return new SameThreadExecutorService();
90   }
91 
92   // See sameThreadExecutor javadoc for behavioral notes.
93   @SingleThreaded
94   public static class SameThreadExecutorService extends AbstractExecutorService {
95      /**
96       * Lock used whenever accessing the state variables (runningTasks, shutdown,
97       * terminationCondition) of the executor
98       */
99      private final Lock lock = new ReentrantLock();
100 
101      /** Signaled after the executor is shutdown and running tasks are done */
102      private final Condition termination = lock.newCondition();
103 
104      private SameThreadExecutorService() {
105      }
106 
107      /*
108       * Conceptually, these two variables describe the executor being in one of three states: -
109       * Active: shutdown == false - Shutdown: runningTasks > 0 and shutdown == true - Terminated:
110       * runningTasks == 0 and shutdown == true
111       */
112      private int runningTasks = 0;
113      private boolean shutdown = false;
114 
115      @Override
116      public void execute(Runnable command) {
117         startTask();
118         try {
119            command.run();
120         } finally {
121            endTask();
122         }
123      }
124 
125      @Override
126      public boolean isShutdown() {
127         lock.lock();
128         try {
129            return shutdown;
130         } finally {
131            lock.unlock();
132         }
133      }
134 
135      @Override
136      public void shutdown() {
137         lock.lock();
138         try {
139            shutdown = true;
140         } finally {
141            lock.unlock();
142         }
143      }
144 
145      // See sameThreadExecutor javadoc for unusual behavior of this method.
146      @Override
147      public List<Runnable> shutdownNow() {
148         shutdown();
149         return Collections.emptyList();
150      }
151 
152      @Override
153      public boolean isTerminated() {
154         lock.lock();
155         try {
156            return shutdown && runningTasks == 0;
157         } finally {
158            lock.unlock();
159         }
160      }
161 
162      @Override
163      public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
164         long nanos = unit.toNanos(timeout);
165         lock.lock();
166         try {
167            for (;;) {
168               if (isTerminated()) {
169                  return true;
170               } else if (nanos <= 0) {
171                  return false;
172               } else {
173                  nanos = termination.awaitNanos(nanos);
174               }
175            }
176         } finally {
177            lock.unlock();
178         }
179      }
180 
181      /**
182       * Checks if the executor has been shut down and increments the running task count.
183       * 
184       * @throws RejectedExecutionException
185       *            if the executor has been previously shutdown
186       */
187      private void startTask() {
188         lock.lock();
189         try {
190            if (isShutdown()) {
191               throw new RejectedExecutionException("Executor already shutdown");
192            }
193            runningTasks++;
194         } finally {
195            lock.unlock();
196         }
197      }
198 
199      /**
200       * Decrements the running task count.
201       */
202      private void endTask() {
203         lock.lock();
204         try {
205            runningTasks--;
206            if (isTerminated()) {
207               termination.signalAll();
208            }
209         } finally {
210            lock.unlock();
211         }
212      }
213   }
214 
215}

[all classes][org.jclouds.concurrent]
EMMA 2.0.5312 (C) Vladimir Roubtsov