public String getGeneralStats() { TextBuilder tb = new TextBuilder(); ThreadFactory tf = _generalThreadPool.getThreadFactory(); if (tf instanceof PriorityThreadFactory) { tb.append("General Thread Pool:\r\n"); tb.append("Tasks in the queue: " + _generalThreadPool.getQueue().size() + "\r\n"); tb.append("Showing threads stack trace:\r\n"); PriorityThreadFactory ptf = (PriorityThreadFactory) tf; int count = ptf.getGroup().activeCount(); Thread[] threads = new Thread[count + 2]; ptf.getGroup().enumerate(threads); tb.append("There should be " + count + " Threads\r\n"); for (Thread t : threads) { if (t == null) { continue; } tb.append(t.getName() + "\r\n"); for (StackTraceElement ste : t.getStackTrace()) { tb.append(ste.toString()); tb.append("\r\n"); } } } tb.append("Packet Tp stack traces printed.\r\n"); return tb.toString(); }
public String getGeneralStats() { final StringBuilder sb = new StringBuilder(1000); ThreadFactory tf = _generalThreadPool.getThreadFactory(); if (tf instanceof PriorityThreadFactory) { PriorityThreadFactory ptf = (PriorityThreadFactory) tf; int count = ptf.getGroup().activeCount(); Thread[] threads = new Thread[count + 2]; ptf.getGroup().enumerate(threads); StringUtil.append( sb, "General Thread Pool:\r\n" + "Tasks in the queue: ", String.valueOf(_generalThreadPool.getQueue().size()), "\r\n" + "Showing threads stack trace:\r\n" + "There should be ", String.valueOf(count), " Threads\r\n"); for (Thread t : threads) { if (t == null) continue; StringUtil.append(sb, t.getName(), "\r\n"); for (StackTraceElement ste : t.getStackTrace()) { StringUtil.append(sb, ste.toString(), "\r\n"); } } } sb.append("Packet Tp stack traces printed.\r\n"); return sb.toString(); }
public void cancel(Runnable runnable) { if (threadPoolExecutor != null && !threadPoolExecutor.isShutdown() && !threadPoolExecutor.isTerminated()) { threadPoolExecutor.remove(runnable); } }
/** Try and stop any action */ public void stop() { // tell the listenee (upstream bean) to stop if (m_listenee instanceof BeanCommon) { // System.err.println("Listener is BeanCommon"); ((BeanCommon) m_listenee).stop(); } if (m_tasks != null) { for (EvaluationTask t : m_tasks) { t.setStopped(); } } m_tasks = null; m_visual.setStatic(); m_setsComplete = 0; // shutdown the executor pool and reclaim storage if (m_executorPool != null) { m_executorPool.shutdownNow(); m_executorPool.purge(); m_executorPool = null; } // stop the evaluate thread /* if (m_evaluateThread != null) { m_evaluateThread.interrupt(); m_evaluateThread.stop(); m_evaluateThread = null; m_visual.setStatic(); } */ }
/* */ public void startDownloading(ThreadPoolExecutor executorService) { /* 70 */ if (this.started) throw new IllegalStateException("Cannot start download job that has already started"); /* 71 */ this.started = true; /* */ /* 73 */ if (this.allFiles.isEmpty()) /* 74 */ System.out.println( "Download job '" + this.name + "' skipped as there are no files to download"); /* */ else { /* 77 */ int threads = executorService.getMaximumPoolSize(); /* 78 */ this.remainingThreads.set(threads); /* 79 */ System.out.println( "Download job '" + this.name + "' started (" + threads + " threads, " + this.allFiles.size() + " files)"); /* 80 */ for (int i = 0; i < threads; i++) /* 81 */ executorService.submit( new Runnable() /* */ { /* */ public void run() { /* 84 */ DownloadJob.this.popAndDownload(); /* */ } /* */ }); /* */ } /* */ }
private void addExecutorForVolume(final File volume) { ThreadFactory threadFactory = new ThreadFactory() { @Override public Thread newThread(Runnable r) { Thread t = new Thread(threadGroup, r); t.setName("Async RamDisk lazy persist worker for volume " + volume); return t; } }; ThreadPoolExecutor executor = new ThreadPoolExecutor( CORE_THREADS_PER_VOLUME, MAXIMUM_THREADS_PER_VOLUME, THREADS_KEEP_ALIVE_SECONDS, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), threadFactory); // This can reduce the number of running threads executor.allowCoreThreadTimeOut(true); executors.put(volume, executor); }
/** * Returns a Thread pool for the RPC's to region replicas. Similar to Connection's thread pool. */ private ExecutorService getDefaultThreadPool(Configuration conf) { int maxThreads = conf.getInt("hbase.region.replica.replication.threads.max", 256); int coreThreads = conf.getInt("hbase.region.replica.replication.threads.core", 16); if (maxThreads == 0) { maxThreads = Runtime.getRuntime().availableProcessors() * 8; } if (coreThreads == 0) { coreThreads = Runtime.getRuntime().availableProcessors() * 8; } long keepAliveTime = conf.getLong("hbase.region.replica.replication.threads.keepalivetime", 60); LinkedBlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>( maxThreads * conf.getInt( HConstants.HBASE_CLIENT_MAX_TOTAL_TASKS, HConstants.DEFAULT_HBASE_CLIENT_MAX_TOTAL_TASKS)); ThreadPoolExecutor tpe = new ThreadPoolExecutor( coreThreads, maxThreads, keepAliveTime, TimeUnit.SECONDS, workQueue, Threads.newDaemonThreadFactory(this.getClass().getSimpleName() + "-rpc-shared-")); tpe.allowCoreThreadTimeOut(true); return tpe; }
public static void main(String[] args) throws Exception { if (args.length != 5) { System.out.println( "usage: Main riakurl bucketName filename filetype(1=accesslog,2=pgdump) threads"); System.exit(0); } fileType = Integer.parseInt(args[3]); threads = Integer.parseInt(args[4]); threadPoolExecutor = new ThreadPoolExecutor( threads, threads, 1, TimeUnit.DAYS, new ArrayBlockingQueue<Runnable>(threads)); String url = args[0]; File inputFile = new File(args[2]); bucketName = args[1]; BufferedReader br = new BufferedReader(new FileReader(inputFile)); int lines = 0; if (fileType == FILETYPE_PG_DUMP) headers = br.readLine().split(";"); while (br.ready()) { lines++; String line = br.readLine(); processLine(line); if (lines >= BATCH_SIZE) { while (threadPoolExecutor.getQueue().size() >= threads - 1) Thread.sleep(1000); threadPoolExecutor.execute(new RiakDumper(url, blogStats)); currentTimeStamp = parsedTimestamp; lines = 0; blogStats = new BlogStats(); } } }
public static void main(String[] args) { BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>(12); ThreadFactory threadFactory = new ThreadFactory() { public Thread newThread(Runnable r) { int currentCount = counter.getAndIncrement(); System.out.println("Creating new thread: " + currentCount); return new Thread(r, "mythread" + currentCount); } }; RejectedExecutionHandler rejectedHandler = new RejectedExecutionHandler() { public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { if (r instanceof ThreadPoolExecutorExample) { ThreadPoolExecutorExample example = (ThreadPoolExecutorExample) r; System.out.println("Rejecting task with id " + example.getTaskId()); } } }; ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 12, 1, TimeUnit.SECONDS, queue, threadFactory, rejectedHandler); for (int i = 0; i < 100; i++) { executor.execute(new ThreadPoolExecutorExample(i)); } executor.shutdown(); }
@Test public void testNotificationExecutor() throws Exception { ListeningExecutorService executor = SingletonHolder.getDefaultNotificationExecutor(); ThreadPoolExecutor tpExecutor = (ThreadPoolExecutor) setAccessible(executor.getClass().getDeclaredField("delegate")).get(executor); BlockingQueue<Runnable> queue = tpExecutor.getQueue(); for (int idx = 0; idx < 100; idx++) { final int idx2 = idx; logger.info("Adding {}\t{}\t{}", idx, queue.size(), tpExecutor.getActiveCount()); executor.execute( new Runnable() { @Override public void run() { logger.info("in {}", idx2); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } logger.info("out {}", idx2); } }); } executor.shutdown(); executor.awaitTermination(10, TimeUnit.SECONDS); }
/* ------------------------------------------------------------ */ public int getThreads() { if (_executor instanceof ThreadPoolExecutor) { final ThreadPoolExecutor tpe = (ThreadPoolExecutor) _executor; return tpe.getPoolSize(); } return -1; }
@Test public void testAddAndGetTile() throws InterruptedException, FileNotFoundException, IOException { // Input stream to use ImageInputStream stream_in = null; try { stream_in = new FileImageInputStream(TestData.file(this, "world.tiff")); // Input RenderedImage to use final RenderedOp input = ImageReadDescriptor.create( stream_in, 0, false, false, false, null, null, null, null, null); // Boolean used for checking if the conditions are passed final AtomicBoolean passed = new AtomicBoolean(true); // Cache creation final ConcurrentTileCacheMultiMap cache = new ConcurrentTileCacheMultiMap(1000 * 1000, false, 1f, 4); // Selection of one tile from the image Raster data = input.getTile(input.getMinTileX(), input.getMinTileY()); // Setting the tile inside the cache cache.add(input, input.getMinTileX(), input.getMinTileY(), data); // Thread pool to use for doing concurrent access on the cache ThreadPoolExecutor executor = new ThreadPoolExecutor( TOTAL, TOTAL, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1000000)); // Latch used for waiting all the threads to end their work final CountDownLatch latch = new CountDownLatch(TOTAL); // Cycle for launching various requests int counter = TOTAL; while (counter > 0) { executor.execute( new Runnable() { public void run() { // Get the tile to use Raster data = cache.getTile(input, input.getMinTileX(), input.getMinTileY()); if (data == null) { passed.getAndSet(false); } latch.countDown(); } }); // Counter update counter--; } // Waiting all threads to finish latch.await(); // Ensure that all the threads have found the tile Assert.assertTrue(passed.get()); } finally { try { if (stream_in != null) { stream_in.flush(); stream_in.close(); } } catch (Throwable t) { // } } }
@Bean public ApiController apiController(ThreadPoolExecutor executor) { executor.setCorePoolSize(4); executor.setMaximumPoolSize(4); ApiController controller = new ApiController(executor); return controller; }
@Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { if (r instanceof AbstractRunnable) { if (((AbstractRunnable) r).isForceExecution()) { BlockingQueue<Runnable> queue = executor.getQueue(); if (!(queue instanceof SizeBlockingQueue)) { throw new IllegalStateException("forced execution, but expected a size queue"); } try { ((SizeBlockingQueue) queue).forcePut(r); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new IllegalStateException("forced execution, but got interrupted", e); } return; } } rejected.inc(); StringBuilder sb = new StringBuilder("rejected execution "); if (executor.isShutdown()) { sb.append(SHUTTING_DOWN_KEY + " "); } else { if (executor.getQueue() instanceof SizeBlockingQueue) { sb.append("(queue capacity ") .append(((SizeBlockingQueue) executor.getQueue()).capacity()) .append(") "); } } sb.append("on ").append(r.toString()); throw new EsRejectedExecutionException(sb.toString()); }
public static void main(String[] args) { ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) Executors.newFixedThreadPool(20); // 创建一个线程池 final Semaphore semaphore = new Semaphore(5); // 设置一个信号量,其值为5,代表共享区一次只能有5个线程同时访问 for (int i = 0; i < 100; i++) { final int threadIndex = i; // 给每个线程一个标志 Runnable runnable = new Runnable() { public void run() { try { semaphore.acquire(); System.out.println("Access:" + threadIndex + "线程正在运行....."); TimeUnit.MILLISECONDS.sleep(5000); semaphore.release(); System.out.println("还有" + semaphore.availablePermits() + "个资源可以用\n"); } catch (InterruptedException e) { e.printStackTrace(); } } }; threadPoolExecutor.execute(runnable); // 将线程放入线程池,让线程池去执行 } threadPoolExecutor.shutdown(); // 结束后要关闭线程池 }
@SuppressWarnings("unused") public static void main(String[] args) { ThreadPoolExecutor pool = new ThreadPoolExecutor( 1, Integer.MAX_VALUE, 60, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); // Threads.newDaemonThreadFactory("htable")); for (int i = 0; i < Integer.MAX_VALUE; ++i) { System.out.println("index: " + i); Future<?> future = pool.submit( new Runnable() { @Override public void run() { try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } } }); } }
@Test public void testJedisClusterRunsWithMultithreaded() throws InterruptedException, ExecutionException, IOException { Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>(); jedisClusterNode.add(new HostAndPort("127.0.0.1", 7379)); final JedisCluster jc = new JedisCluster(jedisClusterNode); jc.set("foo", "bar"); ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 100, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10)); List<Future<String>> futures = new ArrayList<Future<String>>(); for (int i = 0; i < 50; i++) { executor.submit( new Callable<String>() { @Override public String call() throws Exception { // FIXME : invalidate slot cache from JedisCluster to test // random connection also does work return jc.get("foo"); } }); } for (Future<String> future : futures) { String value = future.get(); assertEquals("bar", value); } jc.close(); }
private void runProxies( BookStore proxy, int numberOfClients, boolean threadSafe, boolean stateCanBeChanged) throws Exception { ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 5, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10)); CountDownLatch startSignal = new CountDownLatch(1); CountDownLatch doneSignal = new CountDownLatch(numberOfClients); for (int i = 1; i <= numberOfClients; i++) { // here we do a double copy : from proxy to web client and back to proxy BookStore bs = !threadSafe ? JAXRSClientFactory.fromClient( WebClient.fromClient(WebClient.client(proxy)), BookStore.class) : proxy; String bookName = stateCanBeChanged ? Integer.toString(i) : "TheBook"; String bookHeader = stateCanBeChanged ? "value" + i : "CustomValue"; executor.execute( new RootProxyWorker( bs, bookName, bookHeader, startSignal, doneSignal, stateCanBeChanged)); } startSignal.countDown(); doneSignal.await(60, TimeUnit.SECONDS); executor.shutdownNow(); assertEquals("Not all invocations have completed", 0, doneSignal.getCount()); }
/** * Recurse through directories and list all XML files * * @param files * @throws ParserConfigurationException * @throws InterruptedException */ public void walkThroughParse(File[] files) throws ParserConfigurationException, InterruptedException { FileFilter filter = new FileNameExtensionFilter("XML file", "xml"); for (File file : files) { if (file.isDirectory()) { while (pool.getActiveCount() != 0) Thread.currentThread().sleep(1000); walkThroughParse(file.listFiles()); } else if (file.isFile() && file.canRead()) { if (filter.accept(file)) { this.i++; pool.execute( (new ConvertFileThread( this.fileOutputDir, file, this.failFile, this.maxDirs, i, this.total, this.print))); } } } }
@Test @Ignore("NXP-20582: timeout waiting termination") public void testConcurrency() throws Exception { final String seqName = "mt"; int nbCalls = 5000; final UIDSequencer seq = uidGeneratorService.getSequencer(); ThreadPoolExecutor tpe = new ThreadPoolExecutor( 5, 5, 500L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(nbCalls + 1)); for (int i = 0; i < nbCalls; i++) { tpe.submit( new Runnable() { @Override public void run() { seq.getNext(seqName); } }); } tpe.shutdown(); boolean finish = tpe.awaitTermination(20, TimeUnit.SECONDS); assertTrue("timeout", finish); assertEquals(nbCalls + 1, seq.getNext(seqName)); }
public synchronized void stop() { final TServer thriftServer = this.thriftServer; if (thriftServer != null) { this.service.stop(); thriftServer.stop(); final ThreadPoolExecutor connExecutor = this.thriftThreadPerConnExecutor; if (connExecutor != null) { connExecutor.shutdown(); } this.thriftExecutor.shutdown(); try { this.thriftMainThread.join(5000L); // force stop the executor if required if (this.thriftMainThread.isAlive()) { if (connExecutor != null) { connExecutor.shutdownNow(); } this.thriftExecutor.shutdownNow(); this.thriftMainThread.join(); } } catch (InterruptedException ie) { Thread.currentThread().interrupt(); } } }
private static void realMain(String[] args) throws Throwable { final int n = 4; final CyclicBarrier barrier = new CyclicBarrier(2 * n + 1); final ThreadPoolExecutor pool = new ThreadPoolExecutor( n, 2 * n, KEEPALIVE_MS, MILLISECONDS, new SynchronousQueue<Runnable>()); final Runnable r = new Runnable() { public void run() { try { barrier.await(); barrier.await(); } catch (Throwable t) { unexpected(t); } } }; for (int i = 0; i < 2 * n; i++) pool.execute(r); barrier.await(); checkPoolSizes(pool, 2 * n, n, 2 * n); barrier.await(); long nap = KEEPALIVE_MS + (KEEPALIVE_MS >> 2); for (long sleepyTime = 0L; pool.getPoolSize() > n; ) { check((sleepyTime += nap) <= LONG_DELAY_MS); Thread.sleep(nap); } checkPoolSizes(pool, n, n, 2 * n); Thread.sleep(nap); checkPoolSizes(pool, n, n, 2 * n); pool.shutdown(); check(pool.awaitTermination(LONG_DELAY_MS, MILLISECONDS)); }
public static void execute( final String fromDirectoryPath, final String toFirstPartDirectoryPath, final String toSecondPartDirectoryPath) { ThreadPoolExecutor executor = new ThreadPoolExecutor( 100, 500, Long.MAX_VALUE, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>()); long start = System.currentTimeMillis(); List<String> fileNames = produceInput(fromDirectoryPath); long mid = System.currentTimeMillis(); System.out.println( "Time Taken for producing input: " + Double.valueOf((mid - start) / 1000) + " seconds"); for (String filePath : fileNames) { EtlTask readerTask = new FileSystemEtlTask(filePath, toFirstPartDirectoryPath, toSecondPartDirectoryPath); executor.submit(readerTask); } long end = System.currentTimeMillis(); System.out.println( "Time Taken for creating tasks: " + Double.valueOf((end - start) / 1000) + " seconds"); executor.shutdown(); try { executor.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS); long end2 = System.currentTimeMillis(); System.out.println( "Time Taken till termination: " + Double.valueOf((end2 - start) / 1000) + " seconds"); } catch (InterruptedException e) { System.err.println("ThreadPoolExecutor was interrupted"); e.printStackTrace(); } }
/** * Method that will be executed for each rejected task * * @param r Task that has been rejected * @param executor Executor that has rejected the task */ @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { System.out.printf("RejectedTaskController: The task %s has been rejected\n", r.toString()); System.out.printf("RejectedTaskController: %s\n", executor.toString()); System.out.printf("RejectedTaskController: Terminating: %s\n", executor.isTerminating()); System.out.printf("RejectedTaksController: Terminated: %s\n", executor.isTerminated()); }
public PForEquidistant( final int threads, final int first, final int last, final Object... objects) { this.objects = objects; if (threads < 2) { for (int i = first; i <= last; i++) { step(i); } } else { final ThreadPoolExecutor es = UJMPThreadPoolExecutor.getInstance(threads); final Future<?>[] list = new Future[threads]; for (int i = 0; i < threads; i++) { list[i] = es.submit(new StepCallable(first + i, last, threads)); } for (Future<?> f : list) { try { f.get(); } catch (Exception e) { e.printStackTrace(); } } } }
@Override public synchronized void execute(final Runnable command) { Runnable r = new Runnable() { @Override public void run() { command.run(); next(); } }; if (mCachedSerialExecutor.getActiveCount() < serialOneTime) { // 小于单次并发量直接运行 mCachedSerialExecutor.execute(r); } else { // 如果大于并发上限,那么移除最老的任务 if (mQueue.size() >= serialMaxCount) { mQueue.pollFirst(); } // 新任务放在队尾 mQueue.offerLast(r); // 动态获取目前cpu处理器数目,并调整设置。 // int proCount = Runtime.getRuntime().availableProcessors(); // if (proCount != cpuCount) { // cpuCount = proCount; // reSettings(proCount); // } } }
private void update() { // 更新ThreadPoolExecutor int eventThreadPoolSize = this.getSettings().getInteger("hasor.eventThreadPoolSize", 20); ThreadPoolExecutor threadPool = (ThreadPoolExecutor) executorService; threadPool.setCorePoolSize(eventThreadPoolSize); threadPool.setMaximumPoolSize(eventThreadPoolSize); }
@Test public void testConcurrentPutGet() throws NetInfCheckedException, InterruptedException { List<InformationObject> insertedIOs = new ArrayList<InformationObject>(); ThreadPoolExecutor executor = new ThreadPoolExecutor( 5, 10, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10000)); for (int i = 0; i < NODE_NUMBER; i++) { for (int j = 0; j < IOS_PER_NODE; j++) { InformationObject io = createUniqueIO(); executor.execute(new NodePutCommand(resolutionServices.get(i), io)); insertedIOs.add(io); } } for (InformationObject io : insertedIOs) { NodeGetCommand getter = new NodeGetCommand(resolutionServices.get(0), io); executor.execute(getter); getterCommands.add(getter); } executor.shutdown(); executor.awaitTermination(30, TimeUnit.SECONDS); for (NodeGetCommand getter : getterCommands) { Assert.assertTrue(getter.isCorrect()); } }
/* ------------------------------------------------------------ */ public int getIdleThreads() { if (_executor instanceof ThreadPoolExecutor) { final ThreadPoolExecutor tpe = (ThreadPoolExecutor) _executor; return tpe.getPoolSize() - tpe.getActiveCount(); } return -1; }
/** {@inheritDoc} */ @Override protected GridConfiguration getConfiguration(String gridName) throws Exception { GridConfiguration c = super.getConfiguration(gridName); c.setLocalHost(HOST); assert c.getClientConnectionConfiguration() == null; GridClientConnectionConfiguration clientCfg = new GridClientConnectionConfiguration(); clientCfg.setRestTcpPort(REST_TCP_PORT_BASE); GridSslContextFactory sslCtxFactory = sslContextFactory(); if (sslCtxFactory != null) { clientCfg.setRestTcpSslEnabled(true); clientCfg.setRestTcpSslContextFactory(sslCtxFactory); } c.setClientConnectionConfiguration(clientCfg); GridTcpDiscoverySpi disco = new GridTcpDiscoverySpi(); disco.setIpFinder(IP_FINDER); c.setDiscoverySpi(disco); TestCommunicationSpi spi = new TestCommunicationSpi(); spi.setLocalPort(GridTestUtils.getNextCommPort(getClass())); c.setCommunicationSpi(spi); c.setCacheConfiguration( cacheConfiguration(null), cacheConfiguration(PARTITIONED_CACHE_NAME), cacheConfiguration(REPLICATED_CACHE_NAME), cacheConfiguration(REPLICATED_ASYNC_CACHE_NAME)); ThreadPoolExecutor exec = new ThreadPoolExecutor(40, 40, 0, MILLISECONDS, new LinkedBlockingQueue<Runnable>()); exec.prestartAllCoreThreads(); c.setExecutorService(exec); c.setExecutorServiceShutdown(true); ThreadPoolExecutor sysExec = new ThreadPoolExecutor(40, 40, 0, MILLISECONDS, new LinkedBlockingQueue<Runnable>()); sysExec.prestartAllCoreThreads(); c.setSystemExecutorService(sysExec); c.setSystemExecutorServiceShutdown(true); return c; }