| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- // Copyright (C) 2015, Alibaba Cloud Computing
- #ifndef MNS_SDK_UTILS_H
- #define MNS_SDK_UTILS_H
- #include <string>
- #ifdef _WIN32
- #include <memory>
- #include <windows.h>
- #else
- #include <tr1/memory>
- #include <sys/time.h>
- #include <string.h>
- #endif
- #include <stdio.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <iostream>
- #include "mns_exception.h"
- #include "mns_common_tool.h"
- namespace mns
- {
- namespace sdk
- {
- #define MNS_LOCK_SAFE(x) \
- do \
- { \
- int r = (x); \
- if (r != 0) \
- { \
- int e = errno; \
- std::cerr << "MNS_LOCK_SAFE to abort() @ " << __FILE__ << ":" <<__LINE__ << " in " << __FUNCTION__ << std::endl \
- << "Ret:" << r << " errno:" << e << "(" << strerror(e) << ')' << std::endl; \
- abort(); \
- } \
- } while(false)
- class PTMutex
- {
- public:
- PTMutex()
- {
- #ifdef _WIN32
- InitializeCriticalSection(&cs);
- #else
- MNS_LOCK_SAFE(pthread_mutex_init(&mutex, NULL));
- #endif
- }
- ~PTMutex()
- {
- #ifdef _WIN32
- DeleteCriticalSection(&cs);
- #else
- MNS_LOCK_SAFE(pthread_mutex_destroy(&mutex));
- #endif
- }
- void lock()
- {
- #ifdef _WIN32
- EnterCriticalSection(&cs);
- #else
- MNS_LOCK_SAFE(pthread_mutex_lock(&mutex));
- #endif
- }
- void unlock()
- {
- #ifdef _WIN32
- LeaveCriticalSection(&cs);
- #else
- MNS_LOCK_SAFE(pthread_mutex_unlock(&mutex));
- #endif
- }
- #ifdef _WIN32
- CRITICAL_SECTION& get_pthread_mutex()
- {
- return cs;
- }
- #else
- pthread_mutex_t& get_pthread_mutex()
- {
- return mutex;
- }
- #endif
- protected:
- #ifdef _WIN32
- CRITICAL_SECTION cs;
- #else
- mutable pthread_mutex_t mutex;
- #endif
- };
- class PTCond
- {
- public:
- PTCond()
- {
- #ifdef _WIN32
- InitializeConditionVariable(&cond);
- #else
- MNS_LOCK_SAFE(pthread_cond_init(&cond, NULL));
- #endif
- }
- ~PTCond()
- {
- #ifndef _WIN32
- MNS_LOCK_SAFE(pthread_cond_destroy(&cond));
- #endif
- }
- int wait(PTMutex& mutex, int64_t usec)
- {
- #ifdef _WIN32
- if (usec < 0)
- {
- if (SleepConditionVariableCS(&cond, &(mutex.get_pthread_mutex()), INFINITE))
- {
- return 0;
- }
- else
- {
- return GetLastError();
- }
- }
- else
- {
- #define MICROSECONDS_PER_MILLISECOND 1000
- if (SleepConditionVariableCS(&cond, &(mutex.get_pthread_mutex()), (DWORD)usec / MICROSECONDS_PER_MILLISECOND))
- {
- return 0;
- }
- else
- {
- return GetLastError();
- }
- #undef MICROSECONDS_PER_MILLISECOND
- }
- #else
- int ret;
- if (usec == -1)
- {
- // never fail
- ret = pthread_cond_wait(&cond, &mutex.get_pthread_mutex());
- }
- else
- {
- if (usec < 0)
- {
- MNS_THROW(MNSExceptionBase, "PTCond::wait only accepts positve usec (expect usec = -1 for infinity wait)");
- }
- timespec ts;
- timeval tp;
- gettimeofday(&tp, 0);
- #define MICROSECONDS_PER_SECOND 1000000
- #define NANOSECONDS_PER_MICROSECONDS 1000
- /// Calculate "second" part. Caution, usec may exceeds MICROSECONDS_PER_SECOND.
- ts.tv_sec = tp.tv_sec + (usec / MICROSECONDS_PER_SECOND);
- /// Calcuate "microsecond" part.
- int usec_sum = tp.tv_usec + usec % MICROSECONDS_PER_SECOND;
- /// Adjust "second" part if usec_sum exceeds MICROSECONDS_PER_SECOND
- ts.tv_sec += usec_sum / MICROSECONDS_PER_SECOND;
- usec_sum %= MICROSECONDS_PER_SECOND;
- /// Calcuate nanosecond
- ts.tv_nsec = usec_sum * NANOSECONDS_PER_MICROSECONDS;
- #undef MICROSECONDS_PER_SECOND
- #undef NANOSECONDS_PER_MICROSECONDS
- // fail if timed-out or interupted by a signal
- ret = pthread_cond_timedwait(&cond, &mutex.get_pthread_mutex(), &ts);
- }
- return ret;
- #endif
- }
- void signal()
- {
- #ifdef _WIN32
- WakeConditionVariable(&cond);
- #else
- MNS_LOCK_SAFE(pthread_cond_signal(&cond));
- #endif
- }
- protected:
- #ifdef _WIN32
- CONDITION_VARIABLE cond;
- #else
- pthread_cond_t cond;
- #endif
- };
- class WaitObject
- {
- friend class PTScopedLock;
- PTMutex mutex;
- PTCond cond;
- public:
- WaitObject() {}
- int wait(int64_t timeout = -1)
- {
- return cond.wait(mutex, timeout);
- }
- void signal()
- {
- cond.signal();
- }
- };
- typedef std::shared_ptr<WaitObject> WaitObjectPtr;
- class PTScopedLock
- {
- private:
- PTMutex& mDevice;
- PTScopedLock(const PTScopedLock&);
- PTScopedLock& operator=(const PTScopedLock&);
- public:
- // lock when construct
- explicit PTScopedLock(PTMutex& m) : mDevice(m)
- {
- mDevice.lock();
- }
- explicit PTScopedLock(WaitObject& wo) : mDevice(wo.mutex)
- {
- mDevice.lock();
- }
- // unlock when destruct
- ~PTScopedLock()
- {
- mDevice.unlock();
- }
- };
- class MNSUtils
- {
- public:
- static std::string getLastNodeFromURL(const std::string& inputURL);
- static std::string escapeJson(const std::string &s);
- static std::string toJsonStr(const std::map<std::string, std::string>& param);
- };
- }
- }
- #endif
|