Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
H
hpdos
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
SYNERG
hpdos
Commits
b9e98c52
Commit
b9e98c52
authored
Apr 30, 2022
by
Paras Garg
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added basic JNI to send and recived data from c++
parent
36aa2047
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
754 additions
and
41 deletions
+754
-41
code/cppclient/.gitignore
code/cppclient/.gitignore
+3
-1
code/cppclient/Makefile
code/cppclient/Makefile
+43
-15
code/cppclient/header/Hello.h
code/cppclient/header/Hello.h
+37
-0
code/cppclient/header/Logger.hpp
code/cppclient/header/Logger.hpp
+164
-0
code/cppclient/header/MessageFormats.hpp
code/cppclient/header/MessageFormats.hpp
+20
-12
code/cppclient/jsrc/Hello.class
code/cppclient/jsrc/Hello.class
+0
-0
code/cppclient/jsrc/Hello.java
code/cppclient/jsrc/Hello.java
+12
-0
code/cppclient/src/Client.cpp
code/cppclient/src/Client.cpp
+25
-12
code/cppclient/src/Hello.cpp
code/cppclient/src/Hello.cpp
+84
-0
code/cppclient/src/Logger.cpp
code/cppclient/src/Logger.cpp
+365
-0
code/cppclient/src/RdmaClientEndpoint.cpp
code/cppclient/src/RdmaClientEndpoint.cpp
+1
-1
No files found.
code/cppclient/.gitignore
View file @
b9e98c52
.build
.build/*
client
.vscode/*
\ No newline at end of file
.vscode/*
*.log
*.so
\ No newline at end of file
code/cppclient/Makefile
View file @
b9e98c52
SRCS
:=
$(
shell
ls
src/
)
TARGET
:=
client
# export LD_LIBRARY_PATH=.
#java path /usr/lib/jvm/java-11-openjdk-amd64/
SRC_DIR
:=
src
OBJS
:=
$(SRCS:.cpp=.o)
BUILD_DIR
:=
.build
HEADERS
:=
$(
shell
find
-name
'*.hpp'
)
OBJS
:=
$(
addprefix
$(BUILD_DIR)
/,
$(OBJS)
)
OBJ_DIR
:=
.build
JBUILD
=
.jbin
JSRCS
:=
$(
wildcard
jsrc/
*
.java
)
SRCS
:=
$(
wildcard
$(SRC_DIR)
/
*
.cpp
)
OBJS
:=
$
(
SRCS:
$(SRC_DIR)
/%.cpp
=
$(OBJ_DIR)
/%.o
)
#SRCS := $(shell ls src/)
#OBJS := $(SRCS:.cpp=.o)
#OBJS := $(addprefix $(BUILD_DIR)/, $(OBJS))
CXX
=
g++
CXXFLAGS
+=
-g
-O3
-Wall
-I
header
#compiling flags
CXXFLAGS
+=
-g
-O3
-Wall
-std
=
c++17
-Iheader
-fPIC
CXXFLAGS
+=
-I
/usr/lib/jvm/java-11-openjdk-amd64/include
CXXFLAGS
+=
-I
/usr/lib/jvm/java-11-openjdk-amd64/include/linux
#libraries
LIBS
+=
-libverbs
LIBS
+=
-lrdmacm
LIBS
+=
-pthread
LIBS
+=
-lrocksdb
Target
:=
client
.phony
=
clean
$(BUILD_DIR)/%.o
:
$(SRC_DIR)/%.cpp
$(OBJ_DIR)/%.o
:
$(SRC_DIR)/%.cpp
$(CXX)
-o
$@
$(CXXFLAGS)
-c
$<
$(LIBS)
$(Target)
:
$(OBJS) | $(BUILD_DIR)
@
echo
"Compiled "
$<
" successfully!"
#$(BINDIR)/$(TARGET): $(OBJS)
$(TARGET)
:
$(OBJS)
$(CXX)
-o
$@
$^
$(LIBS)
$(BUILD_DIR)
:
mkdir
-p
$@
\ No newline at end of file
@
echo
"Linked "
$<
" successfully!"
.PHONY
=
clean
clean
:
rm
-f
$(OBJ_DIR)
/
*
rm
-f
$(TARGET)
.PHONY
:
count
count
:
find
.
-type
f
-name
"*.hpp"
|xargs
wc
-l
find
.
-type
f
-name
"*.cpp"
|xargs
wc
-l
@
echo
"Lines of code counted!"
Jclient
:
$(OBJS)
$(CXX)
-o
libHelloImpl.so
-shared
.build/Hello.o
$(LIBS)
@
echo
"jclient "
$<
" successfully!"
#jcompile: javac $(JSRCS) -d JBUILD
JniHeader
:
javac
$(JSRCS)
-h
header
\ No newline at end of file
code/cppclient/header/Hello.h
0 → 100644
View file @
b9e98c52
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Hello */
#ifndef _Included_Hello
#define _Included_Hello
#ifdef __cplusplus
extern
"C"
{
#endif
/*
* Class: Hello
* Method: put
* Signature: ([B[B)I
*/
JNIEXPORT
jint
JNICALL
Java_Hello_put
(
JNIEnv
*
,
jobject
,
jbyteArray
,
jbyteArray
);
/*
* Class: Hello
* Method: get
* Signature: ([B)[B
*/
JNIEXPORT
jbyteArray
JNICALL
Java_Hello_get
(
JNIEnv
*
,
jobject
,
jbyteArray
);
/*
* Class: Hello
* Method: delete
* Signature: ([B)I
*/
JNIEXPORT
jint
JNICALL
Java_Hello_delete
(
JNIEnv
*
,
jobject
,
jbyteArray
);
#ifdef __cplusplus
}
#endif
#endif
code/cppclient/header/Logger.hpp
0 → 100644
View file @
b9e98c52
///////////////////////////////////////////////////////////////////////////////
// @File Name: Logger.h //
// @Author: Pankaj Choudhary //
// @Version: 0.0.1 //
// @L.M.D: 13th April 2015 //
// @Description: For Logging into file //
// //
// Detail Description: //
// Implemented complete logging mechanism, Supporting multiple logging type //
// like as file based logging, console base logging etc. It also supported //
// for different log type. //
// //
// Thread Safe logging mechanism. Compatible with VC++ (Windows platform) //
// as well as G++ (Linux platform) //
// //
// Supported Log Type: ERROR, ALARM, ALWAYS, INFO, BUFFER, TRACE, DEBUG //
// //
// No control for ERROR, ALRAM and ALWAYS messages. These type of messages //
// should be always captured. //
// //
// BUFFER log type should be use while logging raw buffer or raw messages //
// //
// Having direct interface as well as C++ Singleton inface. can use //
// whatever interface want. //
// //
///////////////////////////////////////////////////////////////////////////////
#ifndef _LOGGER_H_
#define _LOGGER_H_
// C++ Header File(s)
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#ifdef WIN32
// Win Socket Header File(s)
#include <Windows.h>
#include <process.h>
#else
// POSIX Socket Header File(s)
#include <errno.h>
#include <pthread.h>
#endif
namespace
CPPLog
{
// Direct Interface for logging into log file or console using MACRO(s)
#define LOG_ERROR(x) Logger::getInstance()->error(x)
#define LOG_ALARM(x) Logger::getInstance()->alarm(x)
#define LOG_ALWAYS(x) Logger::getInstance()->always(x)
#define LOG_INFO(x) Logger::getInstance()->info(x)
#define LOG_BUFFER(x) Logger::getInstance()->buffer(x)
#define LOG_TRACE(x) Logger::getInstance()->trace(x)
#define LOG_DEBUG(x) Logger::getInstance()->debug(x)
// enum for LOG_LEVEL
typedef
enum
LOG_LEVEL
{
DISABLE_LOG
=
1
,
LOG_LEVEL_INFO
=
2
,
LOG_LEVEL_BUFFER
=
3
,
LOG_LEVEL_TRACE
=
4
,
LOG_LEVEL_DEBUG
=
5
,
ENABLE_LOG
=
6
,
}
LogLevel
;
// enum for LOG_TYPE
typedef
enum
LOG_TYPE
{
NO_LOG
=
1
,
CONSOLE
=
2
,
FILE_LOG
=
3
,
}
LogType
;
class
Logger
{
public:
static
Logger
*
getInstance
()
throw
();
// Interface for Error Log
void
error
(
const
char
*
text
)
throw
();
void
error
(
std
::
string
&
text
)
throw
();
void
error
(
std
::
ostringstream
&
stream
)
throw
();
// Interface for Alarm Log
void
alarm
(
const
char
*
text
)
throw
();
void
alarm
(
std
::
string
&
text
)
throw
();
void
alarm
(
std
::
ostringstream
&
stream
)
throw
();
// Interface for Always Log
void
always
(
const
char
*
text
)
throw
();
void
always
(
std
::
string
&
text
)
throw
();
void
always
(
std
::
ostringstream
&
stream
)
throw
();
// Interface for Buffer Log
void
buffer
(
const
char
*
text
)
throw
();
void
buffer
(
std
::
string
&
text
)
throw
();
void
buffer
(
std
::
ostringstream
&
stream
)
throw
();
// Interface for Info Log
void
info
(
const
char
*
text
)
throw
();
void
info
(
std
::
string
&
text
)
throw
();
void
info
(
std
::
ostringstream
&
stream
)
throw
();
// Interface for Trace log
void
trace
(
const
char
*
text
)
throw
();
void
trace
(
std
::
string
&
text
)
throw
();
void
trace
(
std
::
ostringstream
&
stream
)
throw
();
// Interface for Debug log
void
debug
(
const
char
*
text
)
throw
();
void
debug
(
std
::
string
&
text
)
throw
();
void
debug
(
std
::
ostringstream
&
stream
)
throw
();
// Error and Alarm log must be always enable
// Hence, there is no interfce to control error and alarm logs
// Interfaces to control log levels
void
updateLogLevel
(
LogLevel
logLevel
);
void
enaleLog
();
// Enable all log levels
void
disableLog
();
// Disable all log levels, except error and alarm
// Interfaces to control log Types
void
updateLogType
(
LogType
logType
);
void
enableConsoleLogging
();
void
enableFileLogging
();
protected:
Logger
();
~
Logger
();
// Wrapper function for lock/unlock
// For Extensible feature, lock and unlock should be in protected
void
lock
();
void
unlock
();
std
::
string
getCurrentTime
();
private:
void
logIntoFile
(
std
::
string
&
data
);
void
logOnConsole
(
std
::
string
&
data
);
Logger
(
const
Logger
&
obj
)
{}
void
operator
=
(
const
Logger
&
obj
)
{}
private:
static
Logger
*
m_Instance
;
std
::
ofstream
m_File
;
#ifdef WIN32
CRITICAL_SECTION
m_Mutex
;
#else
pthread_mutexattr_t
m_Attr
;
pthread_mutex_t
m_Mutex
;
#endif
LogLevel
m_LogLevel
;
LogType
m_LogType
;
};
}
// End of namespace
#endif // End of _LOGGER_H_
code/cppclient/header/MessageFormats.hpp
View file @
b9e98c52
...
...
@@ -7,7 +7,11 @@ enum RequestType
DELETE
,
INVALIDATE
};
enum
ResponseStatus
{
SUCCESS
,
FAILURE
};
struct
__attribute__
((
__packed__
))
SalRequestHeader
{
...
...
@@ -20,25 +24,29 @@ struct __attribute__ ((__packed__)) SalRequestHeader
struct
__attribute__
((
__packed__
))
SalResponseHeader
{
uint32_t
id
;
enum
RequestType
type
;
uint32_t
size
;
enum
ResponseStatus
status
;
/*
* Note value will be present only in case of response status is success
*/
uint32_t
valueSize
;
};
struct
__attribute__
((
__packed__
))
InvRequestHeader
{
//private:
uint32_t
id
;
enum
RequestType
type
;
//public:
uint32_t
keySize
;
uint32_t
keySize
;
};
static
uint32_t
SUCCESS
=
0
;
static
uint32_t
FAILURE
=
1
;
static
int32_t
SalRequestHeaderSize
=
sizeof
(
SalRequestHeader
);
static
int32_t
SalResponseSize
=
sizeof
(
SalResponseHeader
);
struct
__attribute__
((
__packed__
))
InvResponseHeader
{
uint32_t
id
;
enum
ResponseStatus
status
;
};
static
uint32_t
SalRequestHeaderSize
=
sizeof
(
SalRequestHeader
);
static
uint32_t
SalResponseHeaderSize
=
sizeof
(
SalResponseHeader
);
static
uint32_t
InvRequestHeaderSize
=
sizeof
(
InvRequestHeader
);
static
uint32_t
InvResponseHeaderSize
=
sizeof
(
InvResponseHeader
);
#endif
\ No newline at end of file
code/cppclient/jsrc/Hello.class
0 → 100644
View file @
b9e98c52
File added
code/cppclient/jsrc/Hello.java
0 → 100644
View file @
b9e98c52
public
class
Hello
{
public
native
int
put
(
byte
[]
key
,
byte
[]
value
);
public
native
byte
[]
get
(
byte
[]
key
);
public
native
int
delete
(
byte
[]
key
);
static
{
System
.
loadLibrary
(
"HelloImpl"
);
}
public
static
void
main
(
String
[]
args
)
{
Hello
hello
=
new
Hello
();
System
.
out
.
println
(
hello
.
put
(
"paras"
.
getBytes
(),
"garg"
.
getBytes
()));
System
.
out
.
println
(
hello
.
get
(
"paras"
.
getBytes
()));
System
.
out
.
println
(
hello
.
delete
(
"paras"
.
getBytes
()));
}
}
\ No newline at end of file
code/cppclient/src/Client.cpp
View file @
b9e98c52
...
...
@@ -4,33 +4,46 @@
int
main
()
{
RdmaClientEndpointGroup
*
group
=
new
RdmaClientEndpointGroup
(
5
,
5
,
5
,
50
,
5
0
,
0
,
1000
);
RdmaClientEndpointGroup
*
group
=
new
RdmaClientEndpointGroup
(
5
,
5
,
5
,
50
0
,
50
0
,
0
,
1000
);
RdmaClientEndpoint
*
clientEp
=
group
->
createEndpoint
();
clientEp
->
connect
(
"192.168.200.20"
,
"1921"
,
"sal"
);
while
(
!
clientEp
->
isConnected
());
std
::
cout
<<
"client : connected"
<<
std
::
endl
;
char
*
message
=
new
char
[
3
0
];
char
*
message
=
new
char
[
10
0
];
struct
SalRequestHeader
*
request
=
(
struct
SalRequestHeader
*
)
message
;
request
->
id
=
clientEp
->
_requestId
.
fetch_add
(
1
,
std
::
memory_order_relaxed
);
request
->
type
=
RequestType
::
DELETE
;
request
->
keySize
=
14
;
memcpy
((
char
*
)
request
+
SalRequestHeaderSize
,
"key1sendkey1s"
,
13
);
((
char
*
)
request
)[
SalRequestHeaderSize
+
14
]
=
'\0'
;
std
::
cout
<<
"send Request for atomic int "
<<
request
->
id
<<
"
\n
"
;
// memcpy(re->value,"aa",2);
request
->
type
=
RequestType
::
PUT
;
request
->
keySize
=
10
;
request
->
valueSize
=
5
;
memcpy
((
char
*
)
request
+
SalRequestHeaderSize
,
"parasgarg1"
,
10
);
memcpy
((
char
*
)
request
+
SalRequestHeaderSize
+
request
->
keySize
,
"paras"
,
5
);
std
::
cout
<<
"send"
<<
clientEp
->
sendMessage
(
message
,
SalRequestHeaderSize
+
14
)
<<
std
::
endl
;
// std::cout << "send" << clientEp->sendMessage((char*)re, SalRequestHeaderSize + 2) << std::endl;
std
::
cout
<<
"send"
<<
clientEp
->
sendMessage
(
message
,
SalRequestHeaderSize
+
14
)
<<
std
::
endl
;
std
::
cout
<<
"send"
<<
clientEp
->
sendMessage
(
message
,
SalRequestHeaderSize
+
14
)
<<
std
::
endl
;
std
::
cout
<<
"send"
<<
clientEp
->
sendMessage
(
message
,
SalRequestHeaderSize
+
14
)
<<
std
::
endl
;
request
->
id
=
clientEp
->
_requestId
.
fetch_add
(
1
,
std
::
memory_order_relaxed
);
request
->
type
=
RequestType
::
GET
;
request
->
keySize
=
10
;
memcpy
((
char
*
)
request
+
SalRequestHeaderSize
,
"parasgarg1"
,
10
);
std
::
cout
<<
"send"
<<
clientEp
->
sendMessage
(
message
,
SalRequestHeaderSize
+
14
)
<<
std
::
endl
;
std
::
cout
<<
"send"
<<
clientEp
->
sendMessage
(
message
,
SalRequestHeaderSize
+
14
)
<<
std
::
endl
;
request
->
id
=
clientEp
->
_requestId
.
fetch_add
(
1
,
std
::
memory_order_relaxed
);
request
->
type
=
RequestType
::
DELETE
;
request
->
keySize
=
10
;
memcpy
((
char
*
)
request
+
SalRequestHeaderSize
,
"parasgarg1"
,
10
);
std
::
cout
<<
"send"
<<
clientEp
->
sendMessage
(
message
,
SalRequestHeaderSize
+
14
)
<<
std
::
endl
;
std
::
cout
<<
"send"
<<
clientEp
->
sendMessage
(
message
,
SalRequestHeaderSize
+
14
)
<<
std
::
endl
;
int
send
=
0
;
// memcpy(re->value,"aa",2);
int
send
=
0
;
while
(
1
)
{
std
::
cin
>>
send
;
...
...
code/cppclient/src/Hello.cpp
0 → 100644
View file @
b9e98c52
#include <stdio.h>
#include "Hello.h" // generated by javah
#include "RdmaClientEndpoint.hpp"
/*
bool rocksdb_put_helper(JNIEnv* env, ROCKSDB_NAMESPACE::DB* db,
const ROCKSDB_NAMESPACE::WriteOptions& write_options,
ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle,
jbyteArray jkey, jint jkey_off, jint jkey_len,
jbyteArray jval, jint jval_off, jint jval_len) {
jbyte* key = new jbyte[jkey_len];
env->GetByteArrayRegion(jkey, jkey_off, jkey_len, key);
if (env->ExceptionCheck()) {
// exception thrown: ArrayIndexOutOfBoundsException
delete[] key;
return false;
}
jbyte* value = new jbyte[jval_len];
env->GetByteArrayRegion(jval, jval_off, jval_len, value);
if (env->ExceptionCheck()) {
// exception thrown: ArrayIndexOutOfBoundsException
delete[] value;
delete[] key;
return false;
}
*/
JNIEXPORT
jbyteArray
JNICALL
Java_Hello_get
(
JNIEnv
*
jenv
,
jobject
jobj
,
jbyteArray
jkey
)
{
int
keyLen
=
jenv
->
GetArrayLength
(
jkey
);
char
*
key
=
new
char
[
keyLen
];
jenv
->
GetByteArrayRegion
(
jkey
,
0
,
keyLen
,
reinterpret_cast
<
jbyte
*>
(
key
));
if
(
jenv
->
ExceptionCheck
())
{
std
::
cout
<<
"exception occurs get"
<<
std
::
endl
;
delete
[]
key
;
}
std
::
cout
<<
"get "
<<
key
<<
"len "
<<
keyLen
<<
std
::
endl
;
int
valLen
;
valLen
=
6
;
jbyteArray
jvalue
=
jenv
->
NewByteArray
(
valLen
);
jenv
->
SetByteArrayRegion
(
jvalue
,
0
,
5
,
reinterpret_cast
<
const
jbyte
*>
(
"paras"
));
delete
[]
key
;
return
jvalue
;
}
JNIEXPORT
jint
JNICALL
Java_Hello_put
(
JNIEnv
*
jenv
,
jobject
jobj
,
jbyteArray
jkey
,
jbyteArray
jval
)
{
int
keyLen
=
jenv
->
GetArrayLength
(
jkey
);
char
*
key
=
new
char
[
keyLen
];
jenv
->
GetByteArrayRegion
(
jkey
,
0
,
keyLen
,
reinterpret_cast
<
jbyte
*>
(
key
));
int
valLen
=
jenv
->
GetArrayLength
(
jval
);
char
*
val
=
new
char
[
valLen
];
jenv
->
GetByteArrayRegion
(
jval
,
0
,
valLen
,
reinterpret_cast
<
jbyte
*>
(
val
));
if
(
jenv
->
ExceptionCheck
())
{
std
::
cout
<<
"put exception occur"
<<
std
::
endl
;
delete
[]
key
;
delete
[]
val
;
}
std
::
cout
<<
"put "
<<
key
<<
" len "
<<
keyLen
<<
" "
<<
val
<<
" len "
<<
valLen
<<
std
::
endl
;
delete
[]
key
;
delete
[]
val
;
return
1
;
}
JNIEXPORT
jint
JNICALL
Java_Hello_delete
(
JNIEnv
*
jenv
,
jobject
jobj
,
jbyteArray
jkey
)
{
int
keyLen
=
jenv
->
GetArrayLength
(
jkey
);
char
*
key
=
new
char
[
keyLen
];
jenv
->
GetByteArrayRegion
(
jkey
,
0
,
keyLen
,
reinterpret_cast
<
jbyte
*>
(
key
));
if
(
jenv
->
ExceptionCheck
())
{
std
::
cout
<<
"exception occurs delete"
<<
std
::
endl
;
delete
[]
key
;
}
std
::
cout
<<
"delete "
<<
key
<<
"len "
<<
keyLen
<<
std
::
endl
;
delete
[]
key
;
return
1
;
}
\ No newline at end of file
code/cppclient/src/Logger.cpp
0 → 100644
View file @
b9e98c52
///////////////////////////////////////////////////////////////////////////////
// @File Name: Logger.cpp //
// @Author: Pankaj Choudhary //
// @Version: 0.0.1 //
// @L.M.D: 13th April 2015 //
// @Description: For Logging into file //
// //
// Detail Description: //
// Implemented complete logging mechanism, Supporting multiple logging type //
// like as file based logging, console base logging etc. It also supported //
// for different log type. //
// //
// Thread Safe logging mechanism. Compatible with VC++ (Windows platform) //
// as well as G++ (Linux platform) //
// //
// Supported Log Type: ERROR, ALARM, ALWAYS, INFO, BUFFER, TRACE, DEBUG //
// //
// No control for ERROR, ALRAM and ALWAYS messages. These type of messages //
// should be always captured. //
// //
// BUFFER log type should be use while logging raw buffer or raw messages //
// //
// Having direct interface as well as C++ Singleton inface. can use //
// whatever interface want. //
// //
///////////////////////////////////////////////////////////////////////////////
// C++ Header File(s)
#include <iostream>
#include <cstdlib>
#include <ctime>
// Code Specific Header Files(s)
#include "Logger.hpp"
using
namespace
std
;
using
namespace
CPPLog
;
Logger
*
Logger
::
m_Instance
=
0
;
// Log file name. File name should be change from here only
const
string
logFileName
=
"LogFile.log"
;
Logger
::
Logger
()
{
m_File
.
open
(
logFileName
.
c_str
(),
ios
::
out
|
ios
::
app
);
m_LogLevel
=
LOG_LEVEL_TRACE
;
m_LogType
=
FILE_LOG
;
// Initialize mutex
#ifdef WIN32
InitializeCriticalSection
(
&
m_Mutex
);
#else
int
ret
=
0
;
ret
=
pthread_mutexattr_settype
(
&
m_Attr
,
PTHREAD_MUTEX_ERRORCHECK_NP
);
if
(
ret
!=
0
)
{
printf
(
"Logger::Logger() -- Mutex attribute not initialize!!
\n
"
);
exit
(
0
);
}
ret
=
pthread_mutex_init
(
&
m_Mutex
,
&
m_Attr
);
if
(
ret
!=
0
)
{
printf
(
"Logger::Logger() -- Mutex not initialize!!
\n
"
);
exit
(
0
);
}
#endif
}
Logger
::~
Logger
()
{
m_File
.
close
();
#ifdef WIN32
DeleteCriticalSection
(
&
m_Mutex
);
#else
pthread_mutexattr_destroy
(
&
m_Attr
);
pthread_mutex_destroy
(
&
m_Mutex
);
#endif
}
Logger
*
Logger
::
getInstance
()
throw
()
{
if
(
m_Instance
==
0
)
{
m_Instance
=
new
Logger
();
}
return
m_Instance
;
}
void
Logger
::
lock
()
{
#ifdef WIN32
EnterCriticalSection
(
&
m_Mutex
);
#else
pthread_mutex_lock
(
&
m_Mutex
);
#endif
}
void
Logger
::
unlock
()
{
#ifdef WIN32
LeaveCriticalSection
(
&
m_Mutex
);
#else
pthread_mutex_unlock
(
&
m_Mutex
);
#endif
}
void
Logger
::
logIntoFile
(
std
::
string
&
data
)
{
lock
();
m_File
<<
getCurrentTime
()
<<
" "
<<
data
<<
endl
;
unlock
();
}
void
Logger
::
logOnConsole
(
std
::
string
&
data
)
{
cout
<<
getCurrentTime
()
<<
" "
<<
data
<<
endl
;
}
string
Logger
::
getCurrentTime
()
{
return
""
;
string
currTime
;
//Current date/time based on current time
time_t
now
=
time
(
0
);
// Convert current time to string
currTime
.
assign
(
ctime
(
&
now
));
// Last charactor of currentTime is "\n", so remove it
string
currentTime
=
currTime
.
substr
(
0
,
currTime
.
size
()
-
1
);
return
currentTime
;
}
// Interface for Error Log
void
Logger
::
error
(
const
char
*
text
)
throw
()
{
string
data
;
data
.
append
(
"[ERROR]: "
);
data
.
append
(
text
);
// ERROR must be capture
if
(
m_LogType
==
FILE_LOG
)
{
logIntoFile
(
data
);
}
else
if
(
m_LogType
==
CONSOLE
)
{
logOnConsole
(
data
);
}
}
void
Logger
::
error
(
std
::
string
&
text
)
throw
()
{
error
(
text
.
data
());
}
void
Logger
::
error
(
std
::
ostringstream
&
stream
)
throw
()
{
string
text
=
stream
.
str
();
error
(
text
.
data
());
}
// Interface for Alarm Log
void
Logger
::
alarm
(
const
char
*
text
)
throw
()
{
string
data
;
data
.
append
(
"[ALARM]: "
);
data
.
append
(
text
);
// ALARM must be capture
if
(
m_LogType
==
FILE_LOG
)
{
logIntoFile
(
data
);
}
else
if
(
m_LogType
==
CONSOLE
)
{
logOnConsole
(
data
);
}
}
void
Logger
::
alarm
(
std
::
string
&
text
)
throw
()
{
alarm
(
text
.
data
());
}
void
Logger
::
alarm
(
std
::
ostringstream
&
stream
)
throw
()
{
string
text
=
stream
.
str
();
alarm
(
text
.
data
());
}
// Interface for Always Log
void
Logger
::
always
(
const
char
*
text
)
throw
()
{
string
data
;
data
.
append
(
"[ALWAYS]: "
);
data
.
append
(
text
);
// No check for ALWAYS logs
if
(
m_LogType
==
FILE_LOG
)
{
logIntoFile
(
data
);
}
else
if
(
m_LogType
==
CONSOLE
)
{
logOnConsole
(
data
);
}
}
void
Logger
::
always
(
std
::
string
&
text
)
throw
()
{
always
(
text
.
data
());
}
void
Logger
::
always
(
std
::
ostringstream
&
stream
)
throw
()
{
string
text
=
stream
.
str
();
always
(
text
.
data
());
}
// Interface for Buffer Log
void
Logger
::
buffer
(
const
char
*
text
)
throw
()
{
// Buffer is the special case. So don't add log level
// and timestamp in the buffer message. Just log the raw bytes.
if
((
m_LogType
==
FILE_LOG
)
&&
(
m_LogLevel
>=
LOG_LEVEL_BUFFER
))
{
lock
();
m_File
<<
text
<<
endl
;
unlock
();
}
else
if
((
m_LogType
==
CONSOLE
)
&&
(
m_LogLevel
>=
LOG_LEVEL_BUFFER
))
{
cout
<<
text
<<
endl
;
}
}
void
Logger
::
buffer
(
std
::
string
&
text
)
throw
()