Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
别团等shy哥发育
redis
提交
357a8417
R
redis
项目概览
别团等shy哥发育
/
redis
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
redis
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
357a8417
编写于
11月 08, 2010
作者:
D
Damian Janowski & Michel Martens
提交者:
Michel Martens
11月 29, 2010
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Move to struct.
上级
b2a7fd0c
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
34 addition
and
27 deletion
+34
-27
src/networking.c
src/networking.c
+5
-3
src/redis.h
src/redis.h
+11
-6
src/t_list.c
src/t_list.c
+18
-18
未找到文件。
src/networking.c
浏览文件 @
357a8417
...
...
@@ -41,8 +41,10 @@ redisClient *createClient(int fd) {
c
->
reply
=
listCreate
();
listSetFreeMethod
(
c
->
reply
,
decrRefCount
);
listSetDupMethod
(
c
->
reply
,
dupClientReplyValue
);
c
->
blocking_keys
=
NULL
;
c
->
blocking_keys_num
=
0
;
c
->
bstate
.
keys
=
NULL
;
c
->
bstate
.
count
=
0
;
c
->
bstate
.
timeout
=
0
;
c
->
bstate
.
target
=
NULL
;
c
->
io_keys
=
listCreate
();
c
->
watched_keys
=
listCreate
();
listSetFreeMethod
(
c
->
io_keys
,
decrRefCount
);
...
...
@@ -677,7 +679,7 @@ void closeTimedoutClients(void) {
redisLog
(
REDIS_VERBOSE
,
"Closing idle client"
);
freeClient
(
c
);
}
else
if
(
c
->
flags
&
REDIS_BLOCKED
)
{
if
(
c
->
b
lockingto
!=
0
&&
c
->
blockingto
<
now
)
{
if
(
c
->
b
state
.
timeout
!=
0
&&
c
->
bstate
.
timeout
<
now
)
{
addReply
(
c
,
shared
.
nullmultibulk
);
unblockClientWaitingData
(
c
);
}
...
...
src/redis.h
浏览文件 @
357a8417
...
...
@@ -293,6 +293,16 @@ typedef struct multiState {
int
count
;
/* Total number of MULTI commands */
}
multiState
;
typedef
struct
blockingState
{
robj
**
keys
;
/* The key we are waiting to terminate a blocking
* operation such as BLPOP. Otherwise NULL. */
int
count
;
/* Number of blocking keys */
time_t
timeout
;
/* Blocking operation timeout. If UNIX current time
* is >= timeout then the operation timed out. */
robj
*
target
;
/* The key that should receive the element,
* for BRPOPLPUSH. */
}
blockingState
;
/* With multiplexing we need to take per-clinet state.
* Clients are taken in a liked list. */
typedef
struct
redisClient
{
...
...
@@ -316,12 +326,7 @@ typedef struct redisClient {
long
repldboff
;
/* replication DB file offset */
off_t
repldbsize
;
/* replication DB file size */
multiState
mstate
;
/* MULTI/EXEC state */
robj
**
blocking_keys
;
/* The key we are waiting to terminate a blocking
* operation such as BLPOP. Otherwise NULL. */
int
blocking_keys_num
;
/* Number of blocking keys */
time_t
blockingto
;
/* Blocking operation timeout. If UNIX current time
* is >= blockingto then the operation timed out. */
robj
*
blocking_target
;
blockingState
bstate
;
/* blocking state */
list
*
io_keys
;
/* Keys this client is waiting to be loaded from the
* swap file in order to continue. */
list
*
watched_keys
;
/* Keys WATCHED for MULTI/EXEC CAS */
...
...
src/t_list.c
浏览文件 @
357a8417
...
...
@@ -694,12 +694,12 @@ void blockForKeys(redisClient *c, robj **keys, int numkeys, time_t timeout) {
list
*
l
;
int
j
;
c
->
b
locking_
keys
=
zmalloc
(
sizeof
(
robj
*
)
*
numkeys
);
c
->
b
locking_keys_num
=
numkeys
;
c
->
b
lockingto
=
timeout
;
c
->
b
state
.
keys
=
zmalloc
(
sizeof
(
robj
*
)
*
numkeys
);
c
->
b
state
.
count
=
numkeys
;
c
->
b
state
.
timeout
=
timeout
;
for
(
j
=
0
;
j
<
numkeys
;
j
++
)
{
/* Add the key in the client structure, to map clients -> keys */
c
->
b
locking_
keys
[
j
]
=
keys
[
j
];
c
->
b
state
.
keys
[
j
]
=
keys
[
j
];
incrRefCount
(
keys
[
j
]);
/* And in the other "side", to map keys -> clients */
...
...
@@ -728,22 +728,22 @@ void unblockClientWaitingData(redisClient *c) {
list
*
l
;
int
j
;
redisAssert
(
c
->
b
locking_
keys
!=
NULL
);
redisAssert
(
c
->
b
state
.
keys
!=
NULL
);
/* The client may wait for multiple keys, so unblock it for every key. */
for
(
j
=
0
;
j
<
c
->
b
locking_keys_num
;
j
++
)
{
for
(
j
=
0
;
j
<
c
->
b
state
.
count
;
j
++
)
{
/* Remove this client from the list of clients waiting for this key. */
de
=
dictFind
(
c
->
db
->
blocking_keys
,
c
->
b
locking_
keys
[
j
]);
de
=
dictFind
(
c
->
db
->
blocking_keys
,
c
->
b
state
.
keys
[
j
]);
redisAssert
(
de
!=
NULL
);
l
=
dictGetEntryVal
(
de
);
listDelNode
(
l
,
listSearchKey
(
l
,
c
));
/* If the list is empty we need to remove it to avoid wasting memory */
if
(
listLength
(
l
)
==
0
)
dictDelete
(
c
->
db
->
blocking_keys
,
c
->
b
locking_
keys
[
j
]);
decrRefCount
(
c
->
b
locking_
keys
[
j
]);
dictDelete
(
c
->
db
->
blocking_keys
,
c
->
b
state
.
keys
[
j
]);
decrRefCount
(
c
->
b
state
.
keys
[
j
]);
}
/* Cleanup the client structure */
zfree
(
c
->
b
locking_
keys
);
c
->
b
locking_
keys
=
NULL
;
zfree
(
c
->
b
state
.
keys
);
c
->
b
state
.
keys
=
NULL
;
c
->
flags
&=
(
~
REDIS_BLOCKED
);
server
.
blpop_blocked_clients
--
;
/* We want to process data if there is some command waiting
...
...
@@ -777,7 +777,7 @@ int handleClientsWaitingListPush(redisClient *c, robj *key, robj *ele) {
redisAssert
(
ln
!=
NULL
);
receiver
=
ln
->
value
;
if
(
receiver
->
b
locking_
target
==
NULL
)
{
if
(
receiver
->
b
state
.
target
==
NULL
)
{
addReplyMultiBulkLen
(
receiver
,
2
);
addReplyBulk
(
receiver
,
key
);
addReplyBulk
(
receiver
,
ele
);
...
...
@@ -785,7 +785,7 @@ int handleClientsWaitingListPush(redisClient *c, robj *key, robj *ele) {
else
{
receiver
->
argc
++
;
robj
*
dobj
=
lookupKeyWrite
(
receiver
->
db
,
receiver
->
b
locking_
target
);
robj
*
dobj
=
lookupKeyWrite
(
receiver
->
db
,
receiver
->
b
state
.
target
);
if
(
dobj
&&
checkType
(
receiver
,
dobj
,
REDIS_LIST
))
return
0
;
addReplyBulk
(
receiver
,
ele
);
...
...
@@ -793,7 +793,7 @@ int handleClientsWaitingListPush(redisClient *c, robj *key, robj *ele) {
/* Create the list if the key does not exist */
if
(
!
dobj
)
{
dobj
=
createZiplistObject
();
dbAdd
(
receiver
->
db
,
receiver
->
b
locking_
target
,
dobj
);
dbAdd
(
receiver
->
db
,
receiver
->
b
state
.
target
,
dobj
);
}
listTypePush
(
dobj
,
ele
,
REDIS_HEAD
);
...
...
@@ -833,7 +833,7 @@ void blockingPopGenericCommand(redisClient *c, int where) {
robj
*
argv
[
2
],
**
orig_argv
;
int
orig_argc
;
if
(
c
->
b
locking_
target
==
NULL
)
{
if
(
c
->
b
state
.
target
==
NULL
)
{
/* We need to alter the command arguments before to call
* popGenericCommand() as the command takes a single key. */
orig_argv
=
c
->
argv
;
...
...
@@ -857,8 +857,8 @@ void blockingPopGenericCommand(redisClient *c, int where) {
c
->
argc
=
orig_argc
;
}
else
{
c
->
argv
[
2
]
=
c
->
b
locking_
target
;
c
->
b
locking_
target
=
NULL
;
c
->
argv
[
2
]
=
c
->
b
state
.
target
;
c
->
b
state
.
target
=
NULL
;
rpoplpushCommand
(
c
);
}
...
...
@@ -891,7 +891,7 @@ void brpopCommand(redisClient *c) {
}
void
brpoplpushCommand
(
redisClient
*
c
)
{
c
->
b
locking_
target
=
c
->
argv
[
2
];
c
->
b
state
.
target
=
c
->
argv
[
2
];
c
->
argv
[
2
]
=
c
->
argv
[
3
];
c
->
argc
--
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录