Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-17 08:35:01

0001 /*
0002  * Licensed to the Apache Software Foundation (ASF) under one
0003  * or more contributor license agreements. See the NOTICE file
0004  * distributed with this work for additional information
0005  * regarding copyright ownership. The ASF licenses this file
0006  * to you under the Apache License, Version 2.0 (the
0007  * "License"); you may not use this file except in compliance
0008  * with the License. You may obtain a copy of the License at
0009  *
0010  *   http://www.apache.org/licenses/LICENSE-2.0
0011  *
0012  * Unless required by applicable law or agreed to in writing,
0013  * software distributed under the License is distributed on an
0014  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
0015  * KIND, either express or implied. See the License for the
0016  * specific language governing permissions and limitations
0017  * under the License.
0018  */
0019 
0020 #ifndef _THRIFT_CONCURRENCY_FUNCTION_RUNNER_H
0021 #define _THRIFT_CONCURRENCY_FUNCTION_RUNNER_H 1
0022 
0023 #include <functional>
0024 #include <memory>
0025 
0026 #include <thrift/concurrency/Thread.h>
0027 
0028 namespace apache {
0029 namespace thrift {
0030 namespace concurrency {
0031 
0032 /**
0033  * Convenient implementation of Runnable that will execute arbitrary callbacks.
0034  * Interfaces are provided to accept both a generic 'void(void)' callback, and
0035  * a 'void* (void*)' pthread_create-style callback.
0036  *
0037  * Example use:
0038  *  void* my_thread_main(void* arg);
0039  *  shared_ptr<ThreadFactory> factory = ...;
0040  *  // To create a thread that executes my_thread_main once:
0041  *  shared_ptr<Thread> thread = factory->newThread(
0042  *    FunctionRunner::create(my_thread_main, some_argument));
0043  *  thread->start();
0044  *
0045  *  bool A::foo();
0046  *  A* a = new A();
0047  *  // To create a thread that executes a.foo() every 100 milliseconds:
0048  *  factory->newThread(FunctionRunner::create(
0049  *    std::bind(&A::foo, a), 100))->start();
0050  *
0051  */
0052 
0053 class FunctionRunner : public Runnable {
0054 public:
0055   // This is the type of callback 'pthread_create()' expects.
0056   typedef void* (*PthreadFuncPtr)(void* arg);
0057   // This a fully-generic void(void) callback for custom bindings.
0058   typedef std::function<void()> VoidFunc;
0059 
0060   typedef std::function<bool()> BoolFunc;
0061 
0062   /**
0063    * Syntactic sugar to make it easier to create new FunctionRunner
0064    * objects wrapped in shared_ptr.
0065    */
0066   static std::shared_ptr<FunctionRunner> create(const VoidFunc& cob) {
0067     return std::shared_ptr<FunctionRunner>(new FunctionRunner(cob));
0068   }
0069 
0070   static std::shared_ptr<FunctionRunner> create(PthreadFuncPtr func, void* arg) {
0071     return std::shared_ptr<FunctionRunner>(new FunctionRunner(func, arg));
0072   }
0073 
0074 private:
0075   static void pthread_func_wrapper(PthreadFuncPtr func, void* arg) {
0076     // discard return value
0077     func(arg);
0078   }
0079 
0080 public:
0081   /**
0082    * Given a 'pthread_create' style callback, this FunctionRunner will
0083    * execute the given callback.  Note that the 'void*' return value is ignored.
0084    */
0085   FunctionRunner(PthreadFuncPtr func, void* arg)
0086     : func_(std::bind(pthread_func_wrapper, func, arg)), intervalMs_(-1) {}
0087 
0088   /**
0089    * Given a generic callback, this FunctionRunner will execute it.
0090    */
0091   FunctionRunner(const VoidFunc& cob) : func_(cob), intervalMs_(-1) {}
0092 
0093   /**
0094    * Given a bool foo(...) type callback, FunctionRunner will execute
0095    * the callback repeatedly with 'intervalMs' milliseconds between the calls,
0096    * until it returns false. Note that the actual interval between calls will
0097    * be intervalMs plus execution time of the callback.
0098    */
0099   FunctionRunner(const BoolFunc& cob, int intervalMs) : repFunc_(cob), intervalMs_(intervalMs) {}
0100 
0101   void run() override {
0102     if (repFunc_) {
0103       while (repFunc_()) {
0104         THRIFT_SLEEP_USEC(intervalMs_ * 1000);
0105       }
0106     } else {
0107       func_();
0108     }
0109   }
0110 
0111 private:
0112   VoidFunc func_;
0113   BoolFunc repFunc_;
0114   int intervalMs_;
0115 };
0116 }
0117 }
0118 } // apache::thrift::concurrency
0119 
0120 #endif // #ifndef _THRIFT_CONCURRENCY_FUNCTION_RUNNER_H