Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
hiredis
Commits
96510ce8
Commit
96510ce8
authored
Oct 07, 2010
by
Pieter Noordhuis
Browse files
Factor out reusable include for libevent
parent
b60952f2
Changes
3
Hide whitespace changes
Inline
Side-by-side
Makefile
View file @
96510ce8
...
...
@@ -58,14 +58,14 @@ hiredis-%: %.o ${DYLIBNAME}
test
:
hiredis-test
./hiredis-test
libevent-example
:
libevent-example.c ${DYLIBNAME}
$(CC)
-o
$@
$(CCOPT)
$(DEBUG)
-L
.
-lhiredis
-levent
libevent-example.c
libevent-example
:
extra/hiredis/libevent.h
libevent-example.c ${DYLIBNAME}
$(CC)
-o
$@
$(CCOPT)
$(DEBUG)
-I
.
-Iextra
-L
.
-lhiredis
-levent
libevent-example.c
.c.o
:
$(CC)
-c
$(CFLAGS)
$(DEBUG)
$(COMPILE_TIME)
$<
clean
:
rm
-rf
${DYLIBNAME}
${STLIBNAME}
$(BINS)
*
.o
*
.gcda
*
.gcno
*
.gcov
rm
-rf
${DYLIBNAME}
${STLIBNAME}
$(BINS)
libevent-example
*
.o
*
.gcda
*
.gcno
*
.gcov
dep
:
$(CC)
-MM
*
.c
...
...
extra/hiredis/libevent.h
0 → 100644
View file @
96510ce8
#include <event.h>
#include <hiredis.h>
/* Prototype for the error callback. */
typedef
void
(
redisErrorCallback
)(
redisContext
*
);
/* This struct enables us to pass both the events and the
* redisContext to the read and write handlers. */
typedef
struct
redisEvents
{
redisContext
*
context
;
redisErrorCallback
*
err
;
struct
event
rev
,
wev
;
}
redisEvents
;
void
redisLibEventRead
(
int
fd
,
short
event
,
void
*
arg
)
{
((
void
)
fd
);
((
void
)
event
);
redisEvents
*
e
=
arg
;
/* Always re-schedule read events */
event_add
(
&
e
->
rev
,
NULL
);
if
(
redisBufferRead
(
e
->
context
)
==
REDIS_ERR
)
{
/* Handle error. */
e
->
err
(
e
->
context
);
}
else
{
/* If processing the replies/callbacks results in an error,
* invoke the error callback and abort. */
if
(
redisProcessCallbacks
(
e
->
context
)
==
REDIS_ERR
)
{
e
->
err
(
e
->
context
);
}
}
}
void
redisLibEventWrite
(
int
fd
,
short
event
,
void
*
arg
)
{
((
void
)
fd
);
((
void
)
event
);
redisEvents
*
e
=
arg
;
int
done
=
0
;
if
(
redisBufferWrite
(
e
->
context
,
&
done
)
==
REDIS_ERR
)
{
/* Handle error */
e
->
err
(
e
->
context
);
}
else
{
/* Schedule write event again when writing is not done. */
if
(
!
done
)
{
event_add
(
&
e
->
wev
,
NULL
);
}
else
{
event_add
(
&
e
->
rev
,
NULL
);
}
}
}
/* Schedule to be notified on a write event, so the outgoing buffer
* can be flushed to the socket. */
void
redisLibEventOnWrite
(
redisContext
*
c
,
void
*
privdata
)
{
((
void
)
c
);
redisEvents
*
e
=
privdata
;
event_add
(
&
e
->
wev
,
NULL
);
}
/* Remove event handlers when the context gets disconnected. */
void
redisLibEventOnDisconnect
(
redisContext
*
c
,
void
*
privdata
)
{
((
void
)
c
);
redisEvents
*
e
=
privdata
;
event_del
(
&
e
->
rev
);
event_del
(
&
e
->
wev
);
}
/* Free the redisEvents struct when the context is free'd. */
void
redisLibEventOnFree
(
redisContext
*
c
,
void
*
privdata
)
{
((
void
)
c
);
redisEvents
*
e
=
privdata
;
free
(
e
);
}
redisContext
*
redisLibEventConnect
(
const
char
*
ip
,
int
port
,
redisErrorCallback
*
err
)
{
redisEvents
*
e
;
redisContext
*
c
=
redisConnectNonBlock
(
ip
,
port
,
NULL
);
if
(
c
->
error
!=
NULL
)
{
err
(
c
);
return
NULL
;
}
/* Create container for context and r/w events */
e
=
malloc
(
sizeof
(
*
e
));
e
->
context
=
c
;
e
->
err
=
err
;
/* Register callbacks and events */
redisSetDisconnectCallback
(
e
->
context
,
redisLibEventOnDisconnect
,
e
);
redisSetCommandCallback
(
e
->
context
,
redisLibEventOnWrite
,
e
);
redisSetFreeCallback
(
e
->
context
,
redisLibEventOnFree
,
e
);
event_set
(
&
e
->
rev
,
e
->
context
->
fd
,
EV_READ
,
redisLibEventRead
,
e
);
event_set
(
&
e
->
wev
,
e
->
context
->
fd
,
EV_WRITE
,
redisLibEventWrite
,
e
);
return
e
->
context
;
}
libevent-example.c
View file @
96510ce8
#include <stdio.h>
#include <stdlib.h>
#include <event.h>
#include <string.h>
#include
"
hiredis.h
"
#include
<
hiredis
/libevent
.h
>
#define NOT_USED(x) ((void)x)
void
getCallback
(
redisContext
*
c
,
redisReply
*
reply
,
const
void
*
privdata
)
{
printf
(
"argv[%s]: %s
\n
"
,
(
const
char
*
)
privdata
,
reply
->
reply
);
/* This struct enables us to pass both the event and the
* redisContext to the read and write handlers. */
typedef
struct
redisEvents
{
redisContext
*
context
;
struct
event
rev
,
wev
;
}
redisEvents
;
void
redisLibEventRead
(
int
fd
,
short
event
,
void
*
arg
)
{
NOT_USED
(
fd
);
NOT_USED
(
event
);
redisEvents
*
e
=
arg
;
/* Always re-schedule read events */
event_add
(
&
e
->
rev
,
NULL
);
if
(
redisBufferRead
(
e
->
context
)
==
REDIS_ERR
)
{
/* Handle error. */
printf
(
"Read error: %s
\n
"
,
e
->
context
->
error
);
}
else
{
/* Check replies. */
redisProcessCallbacks
(
e
->
context
);
}
}
void
redisLibEventWrite
(
int
fd
,
short
event
,
void
*
arg
)
{
NOT_USED
(
fd
);
NOT_USED
(
event
);
redisEvents
*
e
=
arg
;
int
done
=
0
;
if
(
redisBufferWrite
(
e
->
context
,
&
done
)
==
REDIS_ERR
)
{
/* Handle error */
printf
(
"Write error: %s
\n
"
,
e
->
context
->
error
);
}
else
{
/* Schedule write event again when writing is not done. */
if
(
!
done
)
{
event_add
(
&
e
->
wev
,
NULL
);
}
else
{
event_add
(
&
e
->
rev
,
NULL
);
}
}
/* Disconnect after receiving the reply to GET */
redisDisconnect
(
c
);
}
/* Schedule to be notified on a write event, so the outgoing buffer
* can be flushed to the socket. */
void
redisLibEventOnWrite
(
redisContext
*
c
,
void
*
privdata
)
{
NOT_USED
(
c
);
redisEvents
*
e
=
privdata
;
event_add
(
&
e
->
wev
,
NULL
);
}
/* Free the redisEvents struct when the context is free'd. */
void
redisLibEventOnFree
(
redisContext
*
c
,
void
*
privdata
)
{
NOT_USED
(
c
);
redisEvents
*
e
=
privdata
;
free
(
e
);
}
void
errorCallback
(
redisContext
*
c
)
{
printf
(
"Error: %s
\n
"
,
c
->
error
);
redisContext
*
redisLibEventConnect
(
const
char
*
ip
,
int
port
)
{
redisEvents
*
e
=
malloc
(
sizeof
(
*
e
));
e
->
context
=
redisConnectNonBlock
(
ip
,
port
,
NULL
);
redisSetCommandCallback
(
e
->
context
,
redisLibEventOnWrite
,
e
);
redisSetFreeCallback
(
e
->
context
,
redisLibEventOnFree
,
e
);
event_set
(
&
e
->
rev
,
e
->
context
->
fd
,
EV_READ
,
redisLibEventRead
,
e
);
event_set
(
&
e
->
wev
,
e
->
context
->
fd
,
EV_WRITE
,
redisLibEventWrite
,
e
);
return
e
->
context
;
}
void
getCallback
(
redisContext
*
c
,
redisReply
*
reply
,
void
*
privdata
)
{
NOT_USED
(
c
);
NOT_USED
(
privdata
);
printf
(
"argv[end-1]: %s
\n
"
,
reply
->
reply
);
/* Clean up the context when there was an error */
redisFree
(
c
);
exit
(
0
);
}
int
main
(
int
argc
,
char
**
argv
)
{
signal
(
SIGPIPE
,
SIG_IGN
);
event_init
();
redisContext
*
c
=
redisLibEventConnect
(
"127.0.0.1"
,
6379
);
if
(
c
->
error
!=
NULL
)
{
printf
(
"Connection error: %s
\n
"
,
c
->
error
);
return
1
;
}
redisContext
*
c
=
redisLibEventConnect
(
"127.0.0.1"
,
6379
,
errorCallback
);
if
(
c
==
NULL
)
return
1
;
redisCommand
(
c
,
"SET key %b"
,
argv
[
argc
-
1
],
strlen
(
argv
[
argc
-
1
]));
redisCommandWithCallback
(
c
,
getCallback
,
NULL
,
"GET key"
);
redisCommandWithCallback
(
c
,
getCallback
,
"end-1"
,
"GET key"
);
event_dispatch
();
redisFree
(
c
);
return
0
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment