122 lines
3.8 KiB
C
122 lines
3.8 KiB
C
|
/*
|
||
|
* 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.
|
||
|
*/
|
||
|
#ifndef THRIFT_ASYNC_TEVENTBASEMANAGER_H
|
||
|
#define THRIFT_ASYNC_TEVENTBASEMANAGER_H 1
|
||
|
|
||
|
#include "thrift/lib/cpp/concurrency/ThreadLocal.h"
|
||
|
|
||
|
namespace apache { namespace thrift { namespace async {
|
||
|
|
||
|
class TEventBase;
|
||
|
|
||
|
/**
|
||
|
* Manager for per-thread TEventBase objects.
|
||
|
* This class will find or create a TEventBase for the current
|
||
|
* thread, associated with thread-specific storage for that thread.
|
||
|
* Although a typical application will generally only have one
|
||
|
* TEventBaseManager, there is no restriction on multiple instances;
|
||
|
* the TEventBases belong to one instance are isolated from those of
|
||
|
* another.
|
||
|
*/
|
||
|
class TEventBaseManager {
|
||
|
public:
|
||
|
TEventBaseManager() {}
|
||
|
~TEventBaseManager() {}
|
||
|
|
||
|
/**
|
||
|
* Get the TEventBase for this thread, or create one if none exists yet.
|
||
|
*
|
||
|
* If no TEventBase exists for this thread yet, a new one will be created and
|
||
|
* returned. May throw std::bad_alloc if allocation fails.
|
||
|
*/
|
||
|
TEventBase* getEventBase() const {
|
||
|
// localStore_.get() will never return NULL.
|
||
|
// InfoManager::allocate() will throw an exception instead if it cannot
|
||
|
// allocate a new EventBaseInfo or TEventBase.
|
||
|
return localStore_.get()->eventBase;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the TEventBase for this thread.
|
||
|
*
|
||
|
* Returns NULL if no TEventBase has been created for this thread yet.
|
||
|
*/
|
||
|
TEventBase* getExistingEventBase() const {
|
||
|
EventBaseInfo* info = localStore_.getNoAlloc();
|
||
|
if (info == NULL) {
|
||
|
return NULL;
|
||
|
}
|
||
|
return info->eventBase;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Set the TEventBase to be used by this thread.
|
||
|
*
|
||
|
* This may only be called if no TEventBase has been defined for this thread
|
||
|
* yet. If a TEventBase is already defined for this thread, a
|
||
|
* TLibraryException is thrown. std::bad_alloc may also be thrown if
|
||
|
* allocation fails while setting the TEventBase.
|
||
|
*
|
||
|
* This should typically be invoked by the code that will call loop() on the
|
||
|
* TEventBase, to make sure the TEventBaseManager points to the correct
|
||
|
* TEventBase that is actually running in this thread.
|
||
|
*/
|
||
|
void setEventBase(TEventBase *eventBase, bool takeOwnership);
|
||
|
|
||
|
/**
|
||
|
* Clear the TEventBase for this thread.
|
||
|
*
|
||
|
* This can be used if the code driving the TEventBase loop() has finished
|
||
|
* the loop and new events should no longer be added to the TEventBase.
|
||
|
*/
|
||
|
void clearEventBase();
|
||
|
|
||
|
private:
|
||
|
struct EventBaseInfo {
|
||
|
EventBaseInfo(TEventBase *evb, bool owned)
|
||
|
: eventBase(evb),
|
||
|
owned(owned) {}
|
||
|
|
||
|
TEventBase *eventBase;
|
||
|
bool owned;
|
||
|
};
|
||
|
|
||
|
class InfoManager {
|
||
|
public:
|
||
|
EventBaseInfo* allocate();
|
||
|
void destroy(EventBaseInfo* info);
|
||
|
|
||
|
void replace(EventBaseInfo* oldInfo, EventBaseInfo* newInfo) {
|
||
|
if (oldInfo != newInfo) {
|
||
|
destroy(oldInfo);
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// Forbidden copy constructor and assignment opererator
|
||
|
TEventBaseManager(TEventBaseManager const &);
|
||
|
TEventBaseManager& operator=(TEventBaseManager const &);
|
||
|
|
||
|
concurrency::ThreadLocal<EventBaseInfo, InfoManager> localStore_;
|
||
|
};
|
||
|
|
||
|
}}} // apache::thrift::async
|
||
|
|
||
|
#endif // THRIFT_ASYNC_TEVENTBASEMANAGER_H
|