/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #include "thrift/lib/cpp/concurrency/TimerManager.h" #include "thrift/lib/cpp/concurrency/PosixThreadFactory.h" #include "thrift/lib/cpp/concurrency/Monitor.h" #include "thrift/lib/cpp/concurrency/Util.h" #include #include namespace apache { namespace thrift { namespace concurrency { namespace test { using namespace apache::thrift::concurrency; /** * ThreadManagerTests class * * @version $Id:$ */ class TimerManagerTests { public: static const double ERROR; class Task: public Runnable { public: Task(Monitor& monitor, int64_t timeout) : _timeout(timeout), _startTime(Util::currentTime()), _monitor(monitor), _success(false), _done(false) {} ~Task() { std::cerr << this << std::endl; } void run() { _endTime = Util::currentTime(); // Figure out error percentage int64_t delta = _endTime - _startTime; delta = delta > _timeout ? delta - _timeout : _timeout - delta; float error = delta / _timeout; if(error < ERROR) { _success = true; } _done = true; std::cout << "\t\t\tTimerManagerTests::Task[" << this << "] done" << std::endl; //debug {Synchronized s(_monitor); _monitor.notifyAll(); } } int64_t _timeout; int64_t _startTime; int64_t _endTime; Monitor& _monitor; bool _success; bool _done; }; /** * This test creates two tasks and waits for the first to expire within 10% * of the expected expiration time. It then verifies that the timer manager * properly clean up itself and the remaining orphaned timeout task when the * manager goes out of scope and its destructor is called. */ bool test00(int64_t timeout=1000LL) { shared_ptr orphanTask = shared_ptr(new TimerManagerTests::Task(_monitor, 10 * timeout)); { TimerManager timerManager; timerManager.threadFactory(shared_ptr(new PosixThreadFactory())); timerManager.start(); assert(timerManager.state() == TimerManager::STARTED); shared_ptr task = shared_ptr(new TimerManagerTests::Task(_monitor, timeout)); { Synchronized s(_monitor); timerManager.add(orphanTask, 10 * timeout); timerManager.add(task, timeout); _monitor.wait(); } assert(task->_done); std::cout << "\t\t\t" << (task->_success ? "Success" : "Failure") << "!" << std::endl; } // timerManager.stop(); This is where it happens via destructor assert(!orphanTask->_done); return true; } friend class TestTask; Monitor _monitor; }; const double TimerManagerTests::ERROR = .20; }}}} // apache::thrift::concurrency