Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
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