|
|
- #include "etsq.h"
-
- ErlNifRWLock *qinfo_map_rwlock;
- QInfoMap qinfo_map;
-
- // Function finds the queue from map and returns QueueInfo
- // Not thread safe.
- QueueInfo* get_q_info(char* name)
- {
- //std::cout<<"Info: "<< name<<std::endl;
- QInfoMap::iterator iter = qinfo_map.find(name);
- if (iter != qinfo_map.end())
- {
- //std::cout<<" Fetched ";
- return iter->second;
- }
- return NULL;
- }
-
- void new_q(char* name)
- {
- //std::cout<<"Create: " << name<<std::endl;
- WriteLock write_lock(qinfo_map_rwlock);
- QueueInfo *queue_info = new QueueInfo(name);
- qinfo_map.insert(QInfoMapPair(name, queue_info));
- //std::cout<<"Created: " << name<<std::endl;
- }
-
- bool push(char* name, ErlTerm *erl_term)
- {
- QueueInfo *pqueue_info = NULL;
- ReadLock read_lock(qinfo_map_rwlock);
- if (NULL != (pqueue_info = get_q_info(name)))
- {
- Mutex mutex(pqueue_info->pmutex);
- pqueue_info->queue.push(erl_term);
- return true;
- }
- return false;
- }
-
- // Returns new ErlTerm. Caller should delete it
- ErlTerm* pop(char* name, bool read_only)
- {
- QueueInfo *pqueue_info = NULL;
- ReadLock read_lock(qinfo_map_rwlock);
- if (NULL != (pqueue_info = get_q_info(name)))
- {
- Mutex mutex(pqueue_info->pmutex);
- if (!pqueue_info->queue.empty())
- {
- ErlTerm *erl_term = pqueue_info->queue.front();
- if(read_only)
- {
- return new ErlTerm(erl_term);
- }
- pqueue_info->queue.pop();
- return erl_term;
- }
- return new ErlTerm("empty");
- }
- return NULL;
- }
-
- static ERL_NIF_TERM new_queue(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
- {
- int size = 100;
- char *name = new char(size);
- enif_get_atom(env, argv[0], name, size, ERL_NIF_LATIN1);
- {
- QueueInfo *pqueue_info = NULL;
- ReadLock read_lock(qinfo_map_rwlock);
- if (NULL != (pqueue_info = get_q_info(name)))
- {
- return enif_make_error(env, "already_exists");
- }
- }
- new_q(name);
- return enif_make_atom(env, "ok");
- }
-
- static ERL_NIF_TERM info(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
- {
- int size = 100;
- char name[100];
- enif_get_atom(env, argv[0], name, size, ERL_NIF_LATIN1);
- int queue_size = 0;
- {
- QueueInfo *pqueue_info = NULL;
- ReadLock read_lock(qinfo_map_rwlock);
- if (NULL == (pqueue_info = get_q_info(name)))
- return enif_make_badarg(env);
- queue_size = pqueue_info->queue.size();
- }
- return enif_make_list2(env,
- enif_make_tuple2(env, enif_make_atom(env, "name"), enif_make_atom(env, name)),
- enif_make_tuple2(env, enif_make_atom(env, "size"), enif_make_int(env, queue_size)));
- }
-
- static ERL_NIF_TERM push_back(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
- {
- int size = 100;
- char name[100];
- enif_get_atom(env, argv[0], name, size, ERL_NIF_LATIN1);
- ErlTerm *erl_term = new ErlTerm(argv[1]);
- if (push(name, erl_term))
- return enif_make_atom(env, "ok");
- delete erl_term;
- return enif_make_badarg(env);
- }
-
- static ERL_NIF_TERM pop_front(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
- {
- int size = 100;
- char name[100];
- enif_get_atom(env, argv[0], name, size, ERL_NIF_LATIN1);
- ErlTerm *erl_term = NULL;
- if (NULL == (erl_term = pop(name, false)))
- return enif_make_badarg(env);
- ERL_NIF_TERM return_term = enif_make_copy(env, erl_term->term);
- delete erl_term;
- return return_term;
- }
-
- static ERL_NIF_TERM get_front(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
- {
- int size = 100;
- char name[100];
- enif_get_atom(env, argv[0], name, size, ERL_NIF_LATIN1);
- ErlTerm *erl_term = NULL;
- if (NULL == (erl_term = pop(name, true)))
- return enif_make_badarg(env);
- ERL_NIF_TERM return_term = enif_make_copy(env, erl_term->term);
- delete erl_term;
- return return_term;
- }
-
- static int is_ok_load_info(ErlNifEnv* env, ERL_NIF_TERM load_info)
- {
- int i;
- return enif_get_int(env, load_info, &i) && i == 1;
- }
-
- static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
- {
- if (!is_ok_load_info(env, load_info))
- return -1;
- qinfo_map_rwlock = enif_rwlock_create((char*)"qinfo");
- return 0;
- }
-
- static int upgrade(ErlNifEnv* env, void** priv_data, void** old_priv_data, ERL_NIF_TERM load_info)
- {
- if (!is_ok_load_info(env, load_info))
- return -1;
- return 0;
- }
-
- static void unload(ErlNifEnv* env, void* priv_data)
- {
- enif_rwlock_destroy(qinfo_map_rwlock);
- }
-
- static ErlNifFunc nif_funcs[] = {
- {"new", 1, new_queue},
- {"info", 1, info},
- {"push_back", 2, push_back},
- {"pop_front", 1, pop_front},
- {"get_front", 1, get_front}
- };
-
- ERL_NIF_INIT(etsq, nif_funcs, load, NULL, upgrade, unload)
|