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
d5fc7d8c
Commit
d5fc7d8c
authored
Nov 01, 2010
by
Pieter Noordhuis
Browse files
Update libev and libevent examples to work with async.h
parent
ac13c9f0
Changes
4
Hide whitespace changes
Inline
Side-by-side
extra/hiredis/libev.h
View file @
d5fc7d8c
#include <sys/types.h>
#include <ev.h>
#include <hiredis.h>
#include <async.h>
/* Prototype for the error callback. */
typedef
void
(
redisErrorCallback
)(
const
redisContext
*
);
typedef
struct
libevRedisEvents
{
redisContext
*
context
;
redisErrorCallback
*
err
;
typedef
struct
redisLibevEvents
{
redisAsyncContext
*
context
;
struct
ev_loop
*
loop
;
int
reading
,
writing
;
ev_io
rev
,
wev
;
}
libevRedis
Events
;
}
redisLibev
Events
;
void
libevRedis
ReadEvent
(
struct
ev_loop
*
loop
,
ev_io
*
watcher
,
int
revents
)
{
void
redisLibev
ReadEvent
(
struct
ev_loop
*
loop
,
ev_io
*
watcher
,
int
revents
)
{
((
void
)
loop
);
((
void
)
revents
);
libevRedisEvents
*
e
=
watcher
->
data
;
if
(
redisBufferRead
(
e
->
context
)
==
REDIS_ERR
)
{
redisDisconnect
(
e
->
context
);
e
->
err
(
e
->
context
);
}
else
{
if
(
redisProcessCallbacks
(
e
->
context
)
==
REDIS_ERR
)
{
redisDisconnect
(
e
->
context
);
e
->
err
(
e
->
context
);
}
}
redisLibevEvents
*
e
=
watcher
->
data
;
redisAsyncHandleRead
(
e
->
context
);
}
void
libevRedis
WriteEvent
(
struct
ev_loop
*
loop
,
ev_io
*
watcher
,
int
revents
)
{
void
redisLibev
WriteEvent
(
struct
ev_loop
*
loop
,
ev_io
*
watcher
,
int
revents
)
{
((
void
)
loop
);
((
void
)
revents
);
libevRedisEvents
*
e
=
watcher
->
data
;
int
done
=
0
;
redisLibevEvents
*
e
=
watcher
->
data
;
redisAsyncHandleWrite
(
e
->
context
);
}
if
(
redisBufferWrite
(
e
->
context
,
&
done
)
==
REDIS_ERR
)
{
redisDisconnect
(
e
->
context
);
e
->
err
(
e
->
context
);
}
else
{
/* Stop firing the write event when done */
if
(
done
)
{
ev_io_stop
(
e
->
loop
,
&
e
->
wev
);
ev_io_start
(
e
->
loop
,
&
e
->
rev
);
}
void
redisLibevAddRead
(
void
*
privdata
)
{
redisLibevEvents
*
e
=
privdata
;
if
(
!
e
->
reading
)
{
e
->
reading
=
1
;
ev_io_start
(
e
->
loop
,
&
e
->
rev
);
}
}
void
libevRedisCommandCallback
(
redisContext
*
c
,
void
*
privdata
)
{
((
void
)
c
);
libevRedisEvents
*
e
=
privdata
;
ev_io_start
(
e
->
loop
,
&
e
->
wev
);
void
redisLibevDelRead
(
void
*
privdata
)
{
redisLibevEvents
*
e
=
privdata
;
if
(
e
->
reading
)
{
e
->
reading
=
0
;
ev_io_stop
(
e
->
loop
,
&
e
->
rev
);
}
}
void
libevRedisDisconnectCallback
(
redisContext
*
c
,
void
*
privdata
)
{
((
void
)
c
);
libevRedisEvents
*
e
=
privdata
;
ev_io_stop
(
e
->
loop
,
&
e
->
rev
);
ev_io_stop
(
e
->
loop
,
&
e
->
wev
);
void
redisLibevAddWrite
(
void
*
privdata
)
{
redisLibevEvents
*
e
=
privdata
;
if
(
!
e
->
writing
)
{
e
->
writing
=
1
;
ev_io_start
(
e
->
loop
,
&
e
->
wev
);
}
}
void
libevRedisFreeCallback
(
redisContext
*
c
,
void
*
privdata
)
{
((
void
)
c
);
libevRedisEvents
*
e
=
privdata
;
void
redisLibevDelWrite
(
void
*
privdata
)
{
redisLibevEvents
*
e
=
privdata
;
if
(
e
->
writing
)
{
e
->
writing
=
0
;
ev_io_stop
(
e
->
loop
,
&
e
->
wev
);
}
}
void
redisLibevCleanup
(
void
*
privdata
)
{
redisLibevEvents
*
e
=
privdata
;
redisLibevDelRead
(
privdata
);
redisLibevDelWrite
(
privdata
);
free
(
e
);
}
redisContext
*
libevRedisConnect
(
struct
ev_loop
*
loop
,
redisErrorCallback
*
err
,
const
char
*
ip
,
int
port
)
{
libevRedisEvents
*
e
;
redisContext
*
c
=
redisConnectNonBlock
(
ip
,
port
,
NULL
);
if
(
c
->
error
!=
NULL
)
{
err
(
c
);
redisFree
(
c
);
return
NULL
;
}
int
redisLibevAttach
(
redisAsyncContext
*
ac
,
struct
ev_loop
*
loop
)
{
redisContext
*
c
=
&
(
ac
->
c
);
redisLibevEvents
*
e
;
/* Nothing should be attached when something is already attached */
if
(
ac
->
data
!=
NULL
)
return
REDIS_ERR
;
/* Create container for context and r/w events */
e
=
malloc
(
sizeof
(
*
e
));
e
->
context
=
c
;
e
->
err
=
err
;
e
->
context
=
ac
;
e
->
loop
=
loop
;
e
->
reading
=
e
->
writing
=
0
;
e
->
rev
.
data
=
e
;
e
->
wev
.
data
=
e
;
/* Register callbacks */
redisSetDisconnectCallback
(
c
,
libevRedisDisconnectCallback
,
e
);
redisSetCommandCallback
(
c
,
libevRedisCommandCallback
,
e
);
redisSetFreeCallback
(
c
,
libevRedisFreeCallback
,
e
);
/* Register functions to start/stop listening for events */
ac
->
evAddRead
=
redisLibevAddRead
;
ac
->
evDelRead
=
redisLibevDelRead
;
ac
->
evAddWrite
=
redisLibevAddWrite
;
ac
->
evDelWrite
=
redisLibevDelWrite
;
ac
->
evCleanup
=
redisLibevCleanup
;
ac
->
data
=
e
;
/* Initialize read/write events */
ev_io_init
(
&
e
->
rev
,
libevRedis
ReadEvent
,
c
->
fd
,
EV_READ
);
ev_io_init
(
&
e
->
wev
,
libevRedis
WriteEvent
,
c
->
fd
,
EV_WRITE
);
return
c
;
ev_io_init
(
&
e
->
rev
,
redisLibev
ReadEvent
,
c
->
fd
,
EV_READ
);
ev_io_init
(
&
e
->
wev
,
redisLibev
WriteEvent
,
c
->
fd
,
EV_WRITE
);
return
REDIS_OK
;
}
extra/hiredis/libevent.h
View file @
d5fc7d8c
#include <sys/types.h>
#include <event.h>
#include <hiredis.h>
#include <async.h>
/* Prototype for the error callback. */
typedef
void
(
redisErrorCallback
)(
const
redisContext
*
);
typedef
struct
libeventRedisEvents
{
redisContext
*
context
;
redisErrorCallback
*
err
;
typedef
struct
redisLibeventEvents
{
redisAsyncContext
*
context
;
struct
event
rev
,
wev
;
}
l
ibevent
Redis
Events
;
}
redisL
ibeventEvents
;
void
l
ibeventRe
disRe
adEvent
(
int
fd
,
short
event
,
void
*
arg
)
{
void
redisL
ibeventReadEvent
(
int
fd
,
short
event
,
void
*
arg
)
{
((
void
)
fd
);
((
void
)
event
);
libeventRedisEvents
*
e
=
arg
;
/* Always re-schedule read events */
event_add
(
&
e
->
rev
,
NULL
);
if
(
redisBufferRead
(
e
->
context
)
==
REDIS_ERR
)
{
redisDisconnect
(
e
->
context
);
e
->
err
(
e
->
context
);
}
else
{
if
(
redisProcessCallbacks
(
e
->
context
)
==
REDIS_ERR
)
{
redisDisconnect
(
e
->
context
);
e
->
err
(
e
->
context
);
}
}
redisLibeventEvents
*
e
=
arg
;
redisAsyncHandleRead
(
e
->
context
);
}
void
l
ibevent
Redis
WriteEvent
(
int
fd
,
short
event
,
void
*
arg
)
{
void
redisL
ibeventWriteEvent
(
int
fd
,
short
event
,
void
*
arg
)
{
((
void
)
fd
);
((
void
)
event
);
libeventRedisEvents
*
e
=
arg
;
int
done
=
0
;
redisLibeventEvents
*
e
=
arg
;
redisAsyncHandleWrite
(
e
->
context
);
}
if
(
redisBufferWrite
(
e
->
context
,
&
done
)
==
REDIS_ERR
)
{
redisDisconnect
(
e
->
context
);
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
);
}
}
void
redisLibeventAddRead
(
void
*
privdata
)
{
redisLibeventEvents
*
e
=
privdata
;
event_add
(
&
e
->
rev
,
NULL
);
}
/* Schedule to be notified on a write event, so the outgoing buffer
* can be flushed to the socket. */
void
libeventRedisCommandCallback
(
redisContext
*
c
,
void
*
privdata
)
{
((
void
)
c
);
libeventRedisEvents
*
e
=
privdata
;
void
redisLibeventDelRead
(
void
*
privdata
)
{
redisLibeventEvents
*
e
=
privdata
;
event_del
(
&
e
->
rev
);
}
void
redisLibeventAddWrite
(
void
*
privdata
)
{
redisLibeventEvents
*
e
=
privdata
;
event_add
(
&
e
->
wev
,
NULL
);
}
/* Remove event handlers when the context gets disconnected. */
void
libeventRedisDisconnectCallback
(
redisContext
*
c
,
void
*
privdata
)
{
((
void
)
c
);
libeventRedisEvents
*
e
=
privdata
;
event_del
(
&
e
->
rev
);
void
redisLibeventDelWrite
(
void
*
privdata
)
{
redisLibeventEvents
*
e
=
privdata
;
event_del
(
&
e
->
wev
);
}
/* Free the libeventRedisEvents struct when the context is free'd. */
void
libeventRedisFreeCallback
(
redisContext
*
c
,
void
*
privdata
)
{
((
void
)
c
);
lib
event
RedisEvents
*
e
=
privdata
;
void
redisLibeventCleanup
(
void
*
privdata
)
{
redisLibeventEvents
*
e
=
privdata
;
event_del
(
&
e
->
rev
);
event
_del
(
&
e
->
wev
)
;
free
(
e
);
}
redisContext
*
libeventRedisConnect
(
struct
event_base
*
base
,
redisErrorCallback
*
err
,
const
char
*
ip
,
int
port
)
{
libeventRedisEvents
*
e
;
redisContext
*
c
=
redisConnectNonBlock
(
ip
,
port
,
NULL
);
if
(
c
->
error
!=
NULL
)
{
err
(
c
);
redisFree
(
c
);
return
NULL
;
}
int
redisLibeventAttach
(
redisAsyncContext
*
ac
,
struct
event_base
*
base
)
{
redisContext
*
c
=
&
(
ac
->
c
);
redisLibeventEvents
*
e
;
/* Nothing should be attached when something is already attached */
if
(
ac
->
data
!=
NULL
)
return
REDIS_ERR
;
/* Create container for context and r/w events */
e
=
malloc
(
sizeof
(
*
e
));
e
->
context
=
c
;
e
->
err
=
err
;
e
->
context
=
ac
;
/* Register callbacks */
redisSetDisconnectCallback
(
c
,
libeventRedisDisconnectCallback
,
e
);
redisSetCommandCallback
(
c
,
libeventRedisCommandCallback
,
e
);
redisSetFreeCallback
(
c
,
libeventRedisFreeCallback
,
e
);
/* Register functions to start/stop listening for events */
ac
->
evAddRead
=
redisLibeventAddRead
;
ac
->
evDelRead
=
redisLibeventDelRead
;
ac
->
evAddWrite
=
redisLibeventAddWrite
;
ac
->
evDelWrite
=
redisLibeventDelWrite
;
ac
->
evCleanup
=
redisLibeventCleanup
;
ac
->
data
=
e
;
/* Initialize and install read/write events */
event_set
(
&
e
->
rev
,
c
->
fd
,
EV_READ
,
l
ibeventRe
disRe
adEvent
,
e
);
event_set
(
&
e
->
wev
,
c
->
fd
,
EV_WRITE
,
l
ibevent
Redis
WriteEvent
,
e
);
event_set
(
&
e
->
rev
,
c
->
fd
,
EV_READ
,
redisL
ibeventReadEvent
,
e
);
event_set
(
&
e
->
wev
,
c
->
fd
,
EV_WRITE
,
redisL
ibeventWriteEvent
,
e
);
event_base_set
(
base
,
&
e
->
rev
);
event_base_set
(
base
,
&
e
->
wev
);
return
c
;
return
REDIS_OK
;
}
libev-example.c
View file @
d5fc7d8c
...
...
@@ -2,30 +2,37 @@
#include <stdlib.h>
#include <string.h>
#include <hiredis/libev.h>
#include <async.h>
#include <signal.h>
void
getCallback
(
redisContext
*
c
,
redisReply
*
reply
,
void
*
privdata
)
{
if
(
reply
==
NULL
)
return
;
/* Error */
printf
(
"argv[%s]: %s
\n
"
,
(
char
*
)
privdata
,
reply
->
reply
);
void
getCallback
(
redisAsyncContext
*
c
,
redisReply
*
reply
,
void
*
privdata
)
{
printf
(
"argv[%s]: %s
\n
"
,
(
char
*
)
privdata
,
reply
->
str
);
/* Disconnect after receiving the reply to GET */
redisDisconnect
(
c
);
redis
Async
Disconnect
(
c
);
}
void
errorCallback
(
const
redisContext
*
c
)
{
printf
(
"Error: %s
\n
"
,
c
->
error
);
void
disconnectCallback
(
const
redisAsyncContext
*
c
,
int
status
)
{
if
(
status
!=
REDIS_OK
)
{
printf
(
"Error: %s
\n
"
,
c
->
error
);
}
}
int
main
(
int
argc
,
char
**
argv
)
{
signal
(
SIGPIPE
,
SIG_IGN
);
struct
ev_loop
*
loop
=
ev_default_loop
(
0
);
redisContext
*
c
=
libevRedisConnect
(
loop
,
errorCallback
,
"127.0.0.1"
,
6379
);
if
(
c
==
NULL
)
return
1
;
redisAsyncContext
*
c
=
redisAsyncConnect
(
"127.0.0.1"
,
6379
);
if
(
c
->
error
!=
NULL
)
{
/* Let *c leak for now... */
printf
(
"Error: %s
\n
"
,
c
->
error
);
return
1
;
}
redisCommand
(
c
,
"SET key %b"
,
argv
[
argc
-
1
],
strlen
(
argv
[
argc
-
1
]));
redisCommandWithCallback
(
c
,
getCallback
,
(
char
*
)
"end-1"
,
"GET key"
);
redisLibevAttach
(
c
,
loop
);
redisAsyncSetDisconnectCallback
(
c
,
disconnectCallback
);
redisAsyncCommand
(
c
,
NULL
,
NULL
,
"SET key %b"
,
argv
[
argc
-
1
],
strlen
(
argv
[
argc
-
1
]));
redisAsyncCommand
(
c
,
getCallback
,
(
char
*
)
"end-1"
,
"GET key"
);
ev_loop
(
loop
,
0
);
redisFree
(
c
);
return
0
;
}
libevent-example.c
View file @
d5fc7d8c
...
...
@@ -2,30 +2,37 @@
#include <stdlib.h>
#include <string.h>
#include <hiredis/libevent.h>
#include <async.h>
#include <signal.h>
void
getCallback
(
redisContext
*
c
,
redisReply
*
reply
,
void
*
privdata
)
{
if
(
reply
==
NULL
)
return
;
/* Error */
printf
(
"argv[%s]: %s
\n
"
,
(
const
char
*
)
privdata
,
reply
->
reply
);
void
getCallback
(
redisAsyncContext
*
c
,
redisReply
*
reply
,
void
*
privdata
)
{
printf
(
"argv[%s]: %s
\n
"
,
(
char
*
)
privdata
,
reply
->
str
);
/* Disconnect after receiving the reply to GET */
redisDisconnect
(
c
);
redis
Async
Disconnect
(
c
);
}
void
errorCallback
(
const
redisContext
*
c
)
{
printf
(
"Error: %s
\n
"
,
c
->
error
);
void
disconnectCallback
(
const
redisAsyncContext
*
c
,
int
status
)
{
if
(
status
!=
REDIS_OK
)
{
printf
(
"Error: %s
\n
"
,
c
->
error
);
}
}
int
main
(
int
argc
,
char
**
argv
)
{
signal
(
SIGPIPE
,
SIG_IGN
);
struct
event_base
*
base
=
event_base_new
();
redisContext
*
c
=
libeventRedisConnect
(
base
,
errorCallback
,
"127.0.0.1"
,
6379
);
if
(
c
==
NULL
)
return
1
;
redisAsyncContext
*
c
=
redisAsyncConnect
(
"127.0.0.1"
,
6379
);
if
(
c
->
error
!=
NULL
)
{
/* Let *c leak for now... */
printf
(
"Error: %s
\n
"
,
c
->
error
);
return
1
;
}
redisCommand
(
c
,
"SET key %b"
,
argv
[
argc
-
1
],
strlen
(
argv
[
argc
-
1
]));
redisCommandWithCallback
(
c
,
getCallback
,
(
char
*
)
"end-1"
,
"GET key"
);
redisLibeventAttach
(
c
,
base
);
redisAsyncSetDisconnectCallback
(
c
,
disconnectCallback
);
redisAsyncCommand
(
c
,
NULL
,
NULL
,
"SET key %b"
,
argv
[
argc
-
1
],
strlen
(
argv
[
argc
-
1
]));
redisAsyncCommand
(
c
,
getCallback
,
(
char
*
)
"end-1"
,
"GET key"
);
event_base_dispatch
(
base
);
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