Skip to content

Instantly share code, notes, and snippets.

@Zetaeta
Created October 24, 2012 22:07
Show Gist options
  • Save Zetaeta/3949237 to your computer and use it in GitHub Desktop.
Save Zetaeta/3949237 to your computer and use it in GitHub Desktop.
#ifndef SCHEDULER_HPP
#define SCHEDULER_HPP
#include <pthread.h>
#include <string>
#include <queue>
#include <tuple>
#ifndef SCHEDULER_SIMPLE_
#include <functional>
#else
#include <Util/stlfwd.hpp>
#endif
#include "Future.hpp"
#include "SchedulerThread.hpp"
namespace MCServer {
using std::forward;
using std::string;
using std::function;
using std::is_convertible;
using std::enable_if;
using std::queue;
using std::vector;
class Scheduler {
public:
Scheduler(int asyncThreadCount = 4);
pthread_t startThread(void * (*function)(void *), void *arg, const string &name = "", pthread_attr_t * = NULL);
template <typename Ret, typename... Args>
inline pthread_t startThread(const string &name, pthread_attr_t *, function<Ret (Args...)> func, Args&&... args);
template <typename Ret, typename... Args>
inline pthread_t startThread(function<Ret (Args...)> func, Args&&... args) {
return startThread("", nullptr, func, forward<Args>(args)...);
}
template <typename Ret, typename... Args>
inline pthread_t startThread(const string &name, function<Ret (Args...)> func, Args&&... args) {
return startThread(name, nullptr, func, forward<Args>(args)...);
}
template <typename Func, typename... Args>
inline auto startThread(Func &&func, Args&&... args) ->
typename enable_if<
is_convertible<
Func, function<decltype(func(args...)) (Args...)>
>::value, pthread_t
>::type {
typedef decltype(func(args...)) ReturnType;
return startThread(function<ReturnType (Args...)>(func), forward<Args>(args)...);
}
template <typename Func, typename... Args>
inline auto startThread(const string &name, Func &&func, Args&&... args) ->
typename enable_if<
is_convertible<
Func, function<decltype(func(args...)) (Args...)>
>::value, pthread_t
>::type {
typedef decltype(func(args...)) ReturnType;
return startThread(name, function<ReturnType (Args...)>(func), forward<Args>(args)...);
}
template <typename Func, typename... Args>
inline auto startThread(const string &name, pthread_attr_t *attr, Func &&func, Args&&... args) ->
typename enable_if<
is_convertible<
Func, function<decltype(func(args...)) (Args...)>
>::value, pthread_t
>::type {
typedef decltype(func(args...)) ReturnType;
return startThread(name, attr, function<ReturnType (Args...)>(func), forward<Args>(args)...);
}
template <typename MemberFunc, typename Class, typename... Args>
inline auto startThread(MemberFunc &&func, Class *obj, Args&&... args) ->
typename enable_if<
is_convertible<
MemberFunc, function<decltype((obj->*func)(args...)) (Args...)>
>::value, pthread_t
>::type {
typedef decltype((obj->*func)(args...)) ReturnType;
return startThread(function<ReturnType (Args...)>(func), obj, forward<Args>(args)...);
}
template <typename MemberFunc, typename Class, typename... Args>
inline auto startThread(const string &name, MemberFunc &&func, Class *obj, Args&&... args) ->
typename enable_if<
is_convertible<
MemberFunc, function<decltype((obj->*func)(args...)) (Args...)>
>::value, pthread_t
>::type {
typedef decltype((obj->*func)(args...)) ReturnType;
return startThread(name, function<ReturnType (Args...)>(func), obj, forward<Args>(args)...);
}
template <typename MemberFunc, typename Class, typename... Args>
inline auto startThread(const string &name, pthread_attr_t *attr, MemberFunc &&func, Class *obj, Args&&... args) ->
typename enable_if<
is_convertible<
MemberFunc, function<decltype((obj->*func)(args...)) (Args...)>
>::value, pthread_t
>::type {
typedef decltype((obj->*func)(args...)) ReturnType;
return startThread(name, attr, function<ReturnType (Args...)>(func), obj, forward<Args>(args)...);
}
template <typename Ret, typename... Args>
Future<Ret> submitAsync(function<Ret (Args...)> func, Args&&... args);
template <typename... Args>
Future<void> submitAsync(function<void (Args...)> func, Args&&... args);
template <typename Func, typename... Args>
inline auto submitAsync(Func &&func, Args&&... args) ->
Future<
typename enable_if<
is_convertible<
Func, function<decltype(func(args...)) (Args...) >
>::value , decltype(func(args...))
>::type
> {
typedef decltype(func(args...)) ReturnType;
return submitAsync(function<ReturnType (Args...)>(func), forward<Args>(args)...);
}
template <typename MemberFunc, typename Class, typename... Args>
inline auto submitAsync(MemberFunc &&func, Class *obj, Args&&... args) ->
Future<
typename enable_if<
is_convertible<
MemberFunc, function<decltype((obj->*func)(args...)) (Args...) >
>::value , decltype((obj->*func)(args...))
>::type
> {
typedef decltype((obj->*func)(args...)) ReturnType;
return submitAsync(function<ReturnType (Args...)>(func), obj, forward<Args>(args)...);
}
template <typename Ret, typename... Args>
Future<Ret> submitSync(function<Ret (Args...)> func, Args&&... args);
template <typename Func, typename... Args>
inline auto submitSync(Func &&func, Args&&... args) ->
Future<
typename enable_if<
is_convertible<
Func, function<decltype(func(args...)) (Args...)>
>::value, decltype(func())
>::type
> {
typedef decltype(func(args...)) ReturnType;
return submitSync(function<ReturnType (Args...)>(func), forward<Args>(args)...);
}
template <typename MemberFunc, typename Class, typename... Args>
inline auto submitSync(MemberFunc &&func, Class *obj, Args&&... args) ->
Future<
typename enable_if<
is_convertible<
MemberFunc, function<decltype((obj->*func)(args...)) (Args...) >
>::value , decltype((obj->*func)(args...))
>::type
> {
typedef decltype((obj->*func)(args...)) ReturnType;
return submitSync(function<ReturnType (Args...)>(func), obj, forward<Args>(args)...);
}
void tick(long millis = -1);
private:
void executeSync(long millis);
void executeSync(const function<void ()> &);
SchedulerThread * getThread();
queue<function<void ()>> asyncFunctions;
queue<function<void ()>> syncFunctions;
vector<SchedulerThread> threads;
pthread_t mainThread;
};
}
#ifndef SCHEDULER_SIMPLE_
#include "Scheduler.tcc"
#endif
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment