Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
varnish-cache
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
varnishcache
varnish-cache
Commits
cbc829fe
Commit
cbc829fe
authored
May 21, 2015
by
Poul-Henning Kamp
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Scrape back the waiter API, and rewrite the poll waiter to handle
sparse fd-sets efficiently.
parent
aeee5b5a
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
122 additions
and
303 deletions
+122
-303
cache.h
bin/varnishd/cache/cache.h
+0
-1
cache_main.c
bin/varnishd/cache/cache_main.c
+0
-3
cache_waiter.c
bin/varnishd/waiter/cache_waiter.c
+5
-204
cache_waiter_poll.c
bin/varnishd/waiter/cache_waiter_poll.c
+112
-82
waiter.h
bin/varnishd/waiter/waiter.h
+0
-1
waiter_priv.h
bin/varnishd/waiter/waiter_priv.h
+5
-12
No files found.
bin/varnishd/cache/cache.h
View file @
cbc829fe
...
@@ -374,7 +374,6 @@ struct waited {
...
@@ -374,7 +374,6 @@ struct waited {
unsigned
magic
;
unsigned
magic
;
#define WAITED_MAGIC 0x1743992d
#define WAITED_MAGIC 0x1743992d
int
fd
;
int
fd
;
VTAILQ_ENTRY
(
waited
)
list
;
void
*
ptr
;
void
*
ptr
;
double
idle
;
double
idle
;
};
};
...
...
bin/varnishd/cache/cache_main.c
View file @
cbc829fe
...
@@ -37,7 +37,6 @@
...
@@ -37,7 +37,6 @@
#include "vcli_priv.h"
#include "vcli_priv.h"
#include "vrnd.h"
#include "vrnd.h"
#include "waiter/waiter.h"
#include "hash/hash_slinger.h"
#include "hash/hash_slinger.h"
...
@@ -213,8 +212,6 @@ child_main(void)
...
@@ -213,8 +212,6 @@ child_main(void)
PAN_Init
();
PAN_Init
();
VFP_Init
();
VFP_Init
();
Waiter_Init
();
VCL_Init
();
VCL_Init
();
HTTP_Init
();
HTTP_Init
();
...
...
bin/varnishd/waiter/cache_waiter.c
View file @
cbc829fe
...
@@ -36,174 +36,17 @@
...
@@ -36,174 +36,17 @@
#include "cache/cache.h"
#include "cache/cache.h"
#include "vfil.h"
#include "vtim.h"
#include "waiter/waiter.h"
#include "waiter/waiter.h"
#include "waiter/waiter_priv.h"
#include "waiter/waiter_priv.h"
#define NEV 8192
static
VTAILQ_HEAD
(,
waiter
)
waiters
=
VTAILQ_HEAD_INITIALIZER
(
waiters
);
static
int
nwaiters
;
static
struct
lock
wait_mtx
;
static
pthread_t
wait_thr
;
static
void
*
wait_poker_thread
(
void
*
arg
)
{
struct
waiter
*
w
;
double
now
;
(
void
)
arg
;
THR_SetName
(
"Waiter timer"
);
while
(
1
)
{
/* Avoid thundering herds and resonances */
(
void
)
usleep
(
990013
/
nwaiters
);
now
=
VTIM_real
();
Lck_Lock
(
&
wait_mtx
);
w
=
VTAILQ_FIRST
(
&
waiters
);
VTAILQ_REMOVE
(
&
waiters
,
w
,
list
);
VTAILQ_INSERT_TAIL
(
&
waiters
,
w
,
list
);
assert
(
w
->
pipes
[
1
]
>=
0
);
if
(
w
->
next_idle
+
*
w
->
tmo
<
now
)
(
void
)
write
(
w
->
pipes
[
1
],
&
w
->
pipe_w
,
sizeof
w
->
pipe_w
);
Lck_Unlock
(
&
wait_mtx
);
}
NEEDLESS_RETURN
(
NULL
);
}
void
Wait_UsePipe
(
struct
waiter
*
w
)
{
CHECK_OBJ_NOTNULL
(
w
,
WAITER_MAGIC
);
AN
(
waiter
->
inject
);
AZ
(
pipe
(
w
->
pipes
));
AZ
(
VFIL_nonblocking
(
w
->
pipes
[
0
]));
AZ
(
VFIL_nonblocking
(
w
->
pipes
[
1
]));
ALLOC_OBJ
(
w
->
pipe_w
,
WAITED_MAGIC
);
w
->
pipe_w
->
fd
=
w
->
pipes
[
0
];
w
->
pipe_w
->
idle
=
0
;
VTAILQ_INSERT_HEAD
(
&
w
->
waithead
,
w
->
pipe_w
,
list
);
waiter
->
inject
(
w
,
w
->
pipe_w
);
}
int
int
Wait_Enter
(
const
struct
waiter
*
w
,
struct
waited
*
wp
)
Wait_Enter
(
const
struct
waiter
*
w
,
struct
waited
*
wp
)
{
{
ssize_t
written
;
uintptr_t
up
;
CHECK_OBJ_NOTNULL
(
w
,
WAITER_MAGIC
);
CHECK_OBJ_NOTNULL
(
w
,
WAITER_MAGIC
);
CHECK_OBJ_NOTNULL
(
wp
,
WAITED_MAGIC
);
CHECK_OBJ_NOTNULL
(
wp
,
WAITED_MAGIC
);
assert
(
wp
->
fd
>
0
);
// stdin never comes here
assert
(
wp
->
fd
>
0
);
// stdin never comes here
AZ
(
w
->
dismantle
);
return
(
w
->
impl
->
enter
(
w
->
priv
,
wp
));
if
(
w
->
impl
->
pass
!=
NULL
)
return
(
w
->
impl
->
pass
(
w
->
priv
,
wp
));
assert
(
w
->
pipes
[
1
]
>
0
);
up
=
(
uintptr_t
)
wp
;
written
=
write
(
w
->
pipes
[
1
],
&
up
,
sizeof
up
);
if
(
written
!=
sizeof
up
&&
(
errno
==
EAGAIN
||
errno
==
EWOULDBLOCK
))
return
(
-
1
);
assert
(
written
==
sizeof
up
);
return
(
0
);
}
static
void
wait_updidle
(
struct
waiter
*
w
,
double
now
)
{
struct
waited
*
wp
;
wp
=
VTAILQ_FIRST
(
&
w
->
waithead
);
if
(
wp
==
NULL
)
return
;
if
(
wp
==
w
->
pipe_w
)
{
VTAILQ_REMOVE
(
&
w
->
waithead
,
wp
,
list
);
VTAILQ_INSERT_TAIL
(
&
w
->
waithead
,
wp
,
list
);
wp
->
idle
=
now
;
wp
=
VTAILQ_FIRST
(
&
w
->
waithead
);
}
w
->
next_idle
=
wp
->
idle
;
}
void
Wait_Handle
(
struct
waiter
*
w
,
struct
waited
*
wp
,
enum
wait_event
ev
,
double
now
)
{
uintptr_t
ss
[
NEV
];
struct
waited
*
wp2
;
int
i
,
j
,
dotimer
=
0
;
CHECK_OBJ_NOTNULL
(
w
,
WAITER_MAGIC
);
CHECK_OBJ_ORNULL
(
wp
,
WAITED_MAGIC
);
if
(
wp
!=
NULL
)
{
if
(
wp
==
w
->
pipe_w
)
{
w
->
do_pipe
=
1
;
VTAILQ_REMOVE
(
&
w
->
waithead
,
w
->
pipe_w
,
list
);
wp
->
idle
=
now
;
VTAILQ_INSERT_TAIL
(
&
w
->
waithead
,
w
->
pipe_w
,
list
);
}
else
{
if
(
w
->
impl
->
evict
!=
NULL
)
w
->
impl
->
evict
(
w
,
wp
);
VTAILQ_REMOVE
(
&
w
->
waithead
,
wp
,
list
);
w
->
func
(
wp
,
ev
,
now
);
wait_updidle
(
w
,
now
);
}
return
;
}
AZ
(
wp
);
if
(
!
w
->
do_pipe
)
return
;
w
->
do_pipe
=
0
;
i
=
read
(
w
->
pipes
[
0
],
ss
,
sizeof
ss
);
if
(
i
==
-
1
&&
errno
==
EAGAIN
)
return
;
for
(
j
=
0
;
i
>=
sizeof
ss
[
0
];
j
++
,
i
-=
sizeof
ss
[
0
])
{
if
(
ss
[
j
]
==
0
)
{
AN
(
w
->
dismantle
);
continue
;
}
ss
[
j
]
&=
~
1
;
CAST_OBJ_NOTNULL
(
wp2
,
(
void
*
)
ss
[
j
],
WAITED_MAGIC
);
if
(
wp2
==
w
->
pipe_w
)
{
dotimer
=
1
;
}
else
{
assert
(
wp2
->
fd
>=
0
);
VTAILQ_INSERT_TAIL
(
&
w
->
waithead
,
wp2
,
list
);
w
->
impl
->
inject
(
w
,
wp2
);
}
}
AZ
(
i
);
wait_updidle
(
w
,
now
);
if
(
!
dotimer
)
return
;
VTAILQ_FOREACH_SAFE
(
wp
,
&
w
->
waithead
,
list
,
wp2
)
{
if
(
wp
==
w
->
pipe_w
)
continue
;
if
(
wp
->
idle
+
*
w
->
tmo
>
now
)
break
;
if
(
w
->
impl
->
evict
!=
NULL
)
w
->
impl
->
evict
(
w
,
wp
);
VTAILQ_REMOVE
(
&
w
->
waithead
,
wp
,
list
);
w
->
func
(
wp
,
WAITER_TIMEOUT
,
now
);
}
wait_updidle
(
w
,
now
);
}
}
/**********************************************************************/
/**********************************************************************/
...
@@ -215,7 +58,7 @@ Waiter_GetName(void)
...
@@ -215,7 +58,7 @@ Waiter_GetName(void)
if
(
waiter
!=
NULL
)
if
(
waiter
!=
NULL
)
return
(
waiter
->
name
);
return
(
waiter
->
name
);
else
else
return
(
"
no_waiter
"
);
return
(
"
(No Waiter?)
"
);
}
}
struct
waiter
*
struct
waiter
*
...
@@ -226,6 +69,8 @@ Waiter_New(waiter_handle_f *func, volatile double *tmo)
...
@@ -226,6 +69,8 @@ Waiter_New(waiter_handle_f *func, volatile double *tmo)
AN
(
waiter
);
AN
(
waiter
);
AN
(
waiter
->
name
);
AN
(
waiter
->
name
);
AN
(
waiter
->
init
);
AN
(
waiter
->
init
);
AN
(
waiter
->
enter
);
AN
(
waiter
->
fini
);
w
=
calloc
(
1
,
sizeof
(
struct
waiter
)
+
waiter
->
size
);
w
=
calloc
(
1
,
sizeof
(
struct
waiter
)
+
waiter
->
size
);
AN
(
w
);
AN
(
w
);
...
@@ -234,20 +79,10 @@ Waiter_New(waiter_handle_f *func, volatile double *tmo)
...
@@ -234,20 +79,10 @@ Waiter_New(waiter_handle_f *func, volatile double *tmo)
w
->
impl
=
waiter
;
w
->
impl
=
waiter
;
w
->
func
=
func
;
w
->
func
=
func
;
w
->
tmo
=
tmo
;
w
->
tmo
=
tmo
;
w
->
pipes
[
0
]
=
w
->
pipes
[
1
]
=
-
1
;
VTAILQ_INIT
(
&
w
->
waithead
);
VTAILQ_INIT
(
&
w
->
waithead
);
waiter
->
init
(
w
);
waiter
->
init
(
w
);
AN
(
w
->
impl
->
pass
||
w
->
pipes
[
1
]
>=
0
);
Lck_Lock
(
&
wait_mtx
);
VTAILQ_INSERT_TAIL
(
&
waiters
,
w
,
list
);
nwaiters
++
;
/* We assume all waiters either use pipes or don't use pipes */
if
(
w
->
pipes
[
1
]
>=
0
&&
nwaiters
==
1
)
AZ
(
pthread_create
(
&
wait_thr
,
NULL
,
wait_poker_thread
,
NULL
));
Lck_Unlock
(
&
wait_mtx
);
return
(
w
);
return
(
w
);
}
}
...
@@ -255,47 +90,13 @@ void
...
@@ -255,47 +90,13 @@ void
Waiter_Destroy
(
struct
waiter
**
wp
)
Waiter_Destroy
(
struct
waiter
**
wp
)
{
{
struct
waiter
*
w
;
struct
waiter
*
w
;
struct
waited
*
wx
=
NULL
;
int
written
;
double
now
;
AN
(
wp
);
AN
(
wp
);
w
=
*
wp
;
w
=
*
wp
;
*
wp
=
NULL
;
*
wp
=
NULL
;
CHECK_OBJ_NOTNULL
(
w
,
WAITER_MAGIC
);
CHECK_OBJ_NOTNULL
(
w
,
WAITER_MAGIC
);
Lck_Lock
(
&
wait_mtx
);
VTAILQ_REMOVE
(
&
waiters
,
w
,
list
);
w
->
dismantle
=
1
;
Lck_Unlock
(
&
wait_mtx
);
if
(
w
->
pipes
[
1
]
>=
0
)
{
while
(
1
)
{
written
=
write
(
w
->
pipes
[
1
],
&
wx
,
sizeof
wx
);
if
(
written
==
sizeof
wx
)
break
;
(
void
)
usleep
(
10000
);
}
}
AN
(
w
->
impl
->
fini
);
AN
(
w
->
impl
->
fini
);
w
->
impl
->
fini
(
w
);
w
->
impl
->
fini
(
w
);
now
=
VTIM_real
();
while
(
1
)
{
wx
=
VTAILQ_FIRST
(
&
w
->
waithead
);
if
(
wx
==
NULL
)
break
;
VTAILQ_REMOVE
(
&
w
->
waithead
,
wx
,
list
);
if
(
wx
==
w
->
pipe_w
)
FREE_OBJ
(
wx
);
else
w
->
func
(
wx
,
WAITER_CLOSE
,
now
);
}
FREE_OBJ
(
w
);
FREE_OBJ
(
w
);
}
}
void
Waiter_Init
(
void
)
{
Lck_New
(
&
wait_mtx
,
lck_misc
);
}
bin/varnishd/waiter/cache_waiter_poll.c
View file @
cbc829fe
...
@@ -45,80 +45,88 @@ struct vwp {
...
@@ -45,80 +45,88 @@ struct vwp {
#define VWP_MAGIC 0x4b2cc735
#define VWP_MAGIC 0x4b2cc735
struct
waiter
*
waiter
;
struct
waiter
*
waiter
;
int
pipes
[
2
];
pthread_t
thread
;
pthread_t
thread
;
struct
pollfd
*
pollfd
;
struct
pollfd
*
pollfd
;
unsigned
npoll
;
struct
waited
**
idx
;
unsigned
hpoll
;
size_t
npoll
;
size_t
hpoll
;
};
};
/*--------------------------------------------------------------------*/
/*--------------------------------------------------------------------
* It would make much more sense to not use two large vectors, but
* the poll(2) API forces us to use at least one, so ... KISS.
*/
static
void
static
void
vwp_
pollspace
(
struct
vwp
*
vwp
,
unsigned
fd
)
vwp_
extend_pollspace
(
struct
vwp
*
vwp
)
{
{
struct
pollfd
*
newpollfd
=
vwp
->
pollfd
;
size_t
inc
=
(
1
<<
16
);
unsigned
newnpoll
;
VSL
(
SLT_Debug
,
0
,
"Acceptor poll space increased by %zu to %zu"
,
if
(
fd
<
vwp
->
npoll
)
inc
,
vwp
->
npoll
+
inc
);
return
;
newnpoll
=
vwp
->
npoll
;
vwp
->
pollfd
=
realloc
(
vwp
->
pollfd
,
if
(
newnpoll
==
0
)
(
vwp
->
npoll
+
inc
)
*
sizeof
(
*
vwp
->
pollfd
));
newnpoll
=
1
;
AN
(
vwp
->
pollfd
);
while
(
fd
>=
newnpoll
)
memset
(
vwp
->
pollfd
+
vwp
->
npoll
,
0
,
inc
*
sizeof
(
*
vwp
->
pollfd
));
newnpoll
=
newnpoll
*
2
;
VSL
(
SLT_Debug
,
0
,
"Acceptor poll space increased to %u"
,
newnpoll
);
vwp
->
idx
=
realloc
(
vwp
->
idx
,
(
vwp
->
npoll
+
inc
)
*
sizeof
(
*
vwp
->
idx
));
newpollfd
=
realloc
(
newpollfd
,
newnpoll
*
sizeof
*
newpollfd
);
AN
(
vwp
->
idx
);
XXXAN
(
newpollfd
);
memset
(
vwp
->
idx
+
vwp
->
npoll
,
0
,
inc
*
sizeof
(
*
vwp
->
idx
));
memset
(
newpollfd
+
vwp
->
npoll
,
0
,
(
newnpoll
-
vwp
->
npoll
)
*
sizeof
*
newpollfd
);
for
(;
inc
>
0
;
inc
--
)
vwp
->
pollfd
=
newpollfd
;
while
(
vwp
->
npoll
<
newnpoll
)
vwp
->
pollfd
[
vwp
->
npoll
++
].
fd
=
-
1
;
vwp
->
pollfd
[
vwp
->
npoll
++
].
fd
=
-
1
;
assert
(
fd
<
vwp
->
npoll
);
}
}
/*--------------------------------------------------------------------*/
/*--------------------------------------------------------------------*/
static
void
__match_proto__
(
waiter_inject_f
)
static
void
vwp_
inject
(
const
struct
waiter
*
w
,
struct
waited
*
wp
)
vwp_
add
(
struct
vwp
*
vwp
,
struct
waited
*
w
)
{
{
struct
vwp
*
vwp
;
int
fd
;
CAST_OBJ_NOTNULL
(
vwp
,
w
->
priv
,
VWP_MAGIC
);
if
(
vwp
->
hpoll
==
vwp
->
npoll
)
CHECK_OBJ_NOTNULL
(
wp
,
WAITED_MAGIC
);
vwp_extend_pollspace
(
vwp
);
fd
=
wp
->
fd
;
assert
(
vwp
->
hpoll
<
vwp
->
npoll
);
VSL
(
SLT_Debug
,
0
,
"POLL Inject %d"
,
fd
);
assert
(
vwp
->
pollfd
[
vwp
->
hpoll
].
fd
==
-
1
);
assert
(
fd
>=
0
);
AZ
(
vwp
->
idx
[
vwp
->
hpoll
]);
vwp_pollspace
(
vwp
,
(
unsigned
)
fd
);
vwp
->
pollfd
[
vwp
->
hpoll
].
fd
=
w
->
fd
;
assert
(
fd
<
vwp
->
npoll
);
vwp
->
pollfd
[
vwp
->
hpoll
].
events
=
POLLIN
;
if
(
vwp
->
hpoll
<
fd
)
vwp
->
idx
[
vwp
->
hpoll
]
=
w
;
vwp
->
hpoll
=
fd
;
vwp
->
hpoll
++
;
assert
(
vwp
->
pollfd
[
fd
].
fd
==
-
1
);
AZ
(
vwp
->
pollfd
[
fd
].
events
);
AZ
(
vwp
->
pollfd
[
fd
].
revents
);
vwp
->
pollfd
[
fd
].
fd
=
fd
;
vwp
->
pollfd
[
fd
].
events
=
POLLIN
;
}
}
static
void
__match_proto__
(
waiter_evict_f
)
static
void
vwp_
evict
(
const
struct
waiter
*
w
,
struct
waited
*
wp
)
vwp_
del
(
struct
vwp
*
vwp
,
int
n
)
{
{
struct
vwp
*
vwp
;
vwp
->
hpoll
--
;
int
fd
;
if
(
n
!=
vwp
->
hpoll
)
{
vwp
->
pollfd
[
n
]
=
vwp
->
pollfd
[
vwp
->
hpoll
];
vwp
->
idx
[
n
]
=
vwp
->
idx
[
vwp
->
hpoll
];
}
memset
(
&
vwp
->
pollfd
[
vwp
->
hpoll
],
0
,
sizeof
(
*
vwp
->
pollfd
));
vwp
->
pollfd
[
vwp
->
hpoll
].
fd
=
-
1
;
vwp
->
idx
[
vwp
->
hpoll
]
=
NULL
;
}
CAST_OBJ_NOTNULL
(
vwp
,
w
->
priv
,
VWP_MAGIC
);
/*--------------------------------------------------------------------*/
CHECK_OBJ_NOTNULL
(
wp
,
WAITED_MAGIC
);
fd
=
wp
->
fd
;
static
void
VSL
(
SLT_Debug
,
0
,
"POLL Evict %d"
,
fd
);
vwp_dopipe
(
struct
vwp
*
vwp
)
assert
(
fd
>=
0
);
{
assert
(
fd
<
vwp
->
npoll
);
struct
waited
*
w
[
128
];
vwp_pollspace
(
vwp
,
(
unsigned
)
fd
);
ssize_t
ss
;
int
i
;
vwp
->
pollfd
[
fd
].
fd
=
-
1
;
vwp
->
pollfd
[
fd
].
events
=
0
;
ss
=
read
(
vwp
->
pipes
[
0
],
w
,
sizeof
w
);
assert
(
ss
>
0
);
i
=
0
;
while
(
ss
)
{
CHECK_OBJ_NOTNULL
(
w
[
i
],
WAITED_MAGIC
);
assert
(
w
[
i
]
->
fd
>
0
);
// no stdin
vwp_add
(
vwp
,
w
[
i
++
]);
}
}
}
/*--------------------------------------------------------------------*/
/*--------------------------------------------------------------------*/
...
@@ -128,50 +136,66 @@ vwp_main(void *priv)
...
@@ -128,50 +136,66 @@ vwp_main(void *priv)
{
{
int
v
,
v2
;
int
v
,
v2
;
struct
vwp
*
vwp
;
struct
vwp
*
vwp
;
struct
waited
*
sp
,
*
sp2
;
struct
waited
*
wp
;
double
now
,
idle
;
double
now
,
idle
;
int
fd
;
int
i
;
CAST_OBJ_NOTNULL
(
vwp
,
priv
,
VWP_MAGIC
);
CAST_OBJ_NOTNULL
(
vwp
,
priv
,
VWP_MAGIC
);
THR_SetName
(
"cache-poll"
);
THR_SetName
(
"cache-poll"
);
while
(
!
vwp
->
waiter
->
dismantle
)
{
while
(
1
)
{
// Try to keep the high point as low as possible
assert
(
vwp
->
hpoll
<
vwp
->
npoll
);
assert
(
vwp
->
hpoll
<
vwp
->
npoll
);
while
(
vwp
->
hpoll
>
0
&&
vwp
->
pollfd
[
vwp
->
hpoll
].
fd
==
-
1
)
while
(
vwp
->
hpoll
>
0
&&
vwp
->
pollfd
[
vwp
->
hpoll
].
fd
==
-
1
)
vwp
->
hpoll
--
;
vwp
->
hpoll
--
;
// XXX: sleep on ->tmo
v
=
poll
(
vwp
->
pollfd
,
vwp
->
hpoll
+
1
,
-
1
);
v
=
poll
(
vwp
->
pollfd
,
vwp
->
hpoll
+
1
,
-
1
);
assert
(
v
>=
0
);
assert
(
v
>=
0
);
v2
=
v
;
v2
=
v
;
now
=
VTIM_real
();
now
=
VTIM_real
();
idle
=
now
-
*
vwp
->
waiter
->
tmo
;
idle
=
now
-
*
vwp
->
waiter
->
tmo
;
VTAILQ_FOREACH_SAFE
(
sp
,
&
vwp
->
waiter
->
waithead
,
list
,
sp2
)
{
i
=
1
;
if
(
v
!=
0
&&
v2
==
0
)
while
(
v2
>
0
&&
i
<
vwp
->
hpoll
)
{
break
;
wp
=
vwp
->
idx
[
i
];
CHECK_OBJ_NOTNULL
(
sp
,
WAITED_MAGIC
);
CHECK_OBJ_NOTNULL
(
wp
,
WAITED_MAGIC
);
fd
=
sp
->
fd
;
if
(
vwp
->
pollfd
[
i
].
revents
!=
0
)
{
VSL
(
SLT_Debug
,
0
,
"POLL Handle %d %x"
,
fd
,
vwp
->
pollfd
[
fd
].
revents
);
assert
(
fd
>=
0
);
assert
(
fd
<=
vwp
->
hpoll
);
assert
(
fd
<
vwp
->
npoll
);
assert
(
vwp
->
pollfd
[
fd
].
fd
==
fd
);
if
(
vwp
->
pollfd
[
fd
].
revents
)
{
v2
--
;
v2
--
;
vwp
->
pollfd
[
fd
].
revents
=
0
;
assert
(
wp
->
fd
>
0
);
Wait_Handle
(
vwp
->
waiter
,
sp
,
WAITER_ACTION
,
assert
(
wp
->
fd
==
vwp
->
pollfd
[
i
].
fd
);
now
);
VSL
(
SLT_Debug
,
wp
->
fd
,
"POLL Handle %d %x"
,
}
else
if
(
sp
->
idle
<=
idle
)
{
wp
->
fd
,
vwp
->
pollfd
[
i
].
revents
);
Wait_Handle
(
vwp
->
waiter
,
sp
,
WAITER_TIMEOUT
,
vwp_del
(
vwp
,
i
);
now
);
vwp
->
waiter
->
func
(
wp
,
WAITER_ACTION
,
now
);
}
else
if
(
wp
->
idle
<=
idle
)
{
vwp_del
(
vwp
,
i
);
vwp
->
waiter
->
func
(
wp
,
WAITER_TIMEOUT
,
now
);
}
else
{
i
++
;
}
}
}
}
Wait_Handle
(
vwp
->
waiter
,
NULL
,
WAITER_ACTION
,
now
);
if
(
vwp
->
pollfd
[
0
].
revents
)
vwp_dopipe
(
vwp
);
}
}
NEEDLESS_RETURN
(
NULL
);
NEEDLESS_RETURN
(
NULL
);
}
}
/*--------------------------------------------------------------------*/
/*--------------------------------------------------------------------*/
static
int
__match_proto__
(
waiter_enter_f
)
vwp_enter
(
void
*
priv
,
struct
waited
*
wp
)
{
struct
vwp
*
vwp
;
CAST_OBJ_NOTNULL
(
vwp
,
priv
,
VWP_MAGIC
);
if
(
write
(
vwp
->
pipes
[
1
],
&
wp
,
sizeof
wp
)
!=
sizeof
wp
)
return
(
-
1
);
return
(
0
);
}
/*--------------------------------------------------------------------*/
static
void
__match_proto__
(
waiter_init_f
)
static
void
__match_proto__
(
waiter_init_f
)
vwp_init
(
struct
waiter
*
w
)
vwp_init
(
struct
waiter
*
w
)
{
{
...
@@ -181,9 +205,13 @@ vwp_init(struct waiter *w)
...
@@ -181,9 +205,13 @@ vwp_init(struct waiter *w)
vwp
=
w
->
priv
;
vwp
=
w
->
priv
;
INIT_OBJ
(
vwp
,
VWP_MAGIC
);
INIT_OBJ
(
vwp
,
VWP_MAGIC
);
vwp
->
waiter
=
w
;
vwp
->
waiter
=
w
;
AZ
(
pipe
(
vwp
->
pipes
));
// XXX: set write pipe non-blocking
vwp_pollspace
(
vwp
,
256
);
vwp_extend_pollspace
(
vwp
);
Wait_UsePipe
(
w
);
vwp
->
pollfd
[
0
].
fd
=
vwp
->
pipes
[
0
];
vwp
->
pollfd
[
0
].
events
=
POLLIN
;
vwp
->
hpoll
=
1
;
AZ
(
pthread_create
(
&
vwp
->
thread
,
NULL
,
vwp_main
,
vwp
));
AZ
(
pthread_create
(
&
vwp
->
thread
,
NULL
,
vwp_main
,
vwp
));
}
}
...
@@ -196,6 +224,9 @@ vwp_fini(struct waiter *w)
...
@@ -196,6 +224,9 @@ vwp_fini(struct waiter *w)
void
*
vp
;
void
*
vp
;
CAST_OBJ_NOTNULL
(
vwp
,
w
->
priv
,
VWP_MAGIC
);
CAST_OBJ_NOTNULL
(
vwp
,
w
->
priv
,
VWP_MAGIC
);
vp
=
NULL
;
// XXX: set write pipe blocking
assert
(
write
(
vwp
->
pipes
[
1
],
&
vp
,
sizeof
vp
)
==
sizeof
vp
);
AZ
(
pthread_join
(
vwp
->
thread
,
&
vp
));
AZ
(
pthread_join
(
vwp
->
thread
,
&
vp
));
free
(
vwp
->
pollfd
);
free
(
vwp
->
pollfd
);
}
}
...
@@ -206,7 +237,6 @@ const struct waiter_impl waiter_poll = {
...
@@ -206,7 +237,6 @@ const struct waiter_impl waiter_poll = {
.
name
=
"poll"
,
.
name
=
"poll"
,
.
init
=
vwp_init
,
.
init
=
vwp_init
,
.
fini
=
vwp_fini
,
.
fini
=
vwp_fini
,
.
inject
=
vwp_inject
,
.
enter
=
vwp_enter
,
.
evict
=
vwp_evict
,
.
size
=
sizeof
(
struct
vwp
),
.
size
=
sizeof
(
struct
vwp
),
};
};
bin/varnishd/waiter/waiter.h
View file @
cbc829fe
...
@@ -61,7 +61,6 @@ int Wait_Enter(const struct waiter *, struct waited *);
...
@@ -61,7 +61,6 @@ int Wait_Enter(const struct waiter *, struct waited *);
struct
waiter
*
Waiter_New
(
waiter_handle_f
*
,
volatile
double
*
timeout
);
struct
waiter
*
Waiter_New
(
waiter_handle_f
*
,
volatile
double
*
timeout
);
void
Waiter_Destroy
(
struct
waiter
**
);
void
Waiter_Destroy
(
struct
waiter
**
);
const
char
*
Waiter_GetName
(
void
);
const
char
*
Waiter_GetName
(
void
);
void
Waiter_Init
(
void
);
/* mgt_waiter.c */
/* mgt_waiter.c */
int
Wait_Argument
(
struct
vsb
*
vsb
,
const
char
*
arg
);
int
Wait_Argument
(
struct
vsb
*
vsb
,
const
char
*
arg
);
bin/varnishd/waiter/waiter_priv.h
View file @
cbc829fe
...
@@ -33,27 +33,25 @@ struct waited;
...
@@ -33,27 +33,25 @@ struct waited;
struct
waiter
{
struct
waiter
{
unsigned
magic
;
unsigned
magic
;
#define WAITER_MAGIC
0x17c399db
#define WAITER_MAGIC
0x17c399db
const
struct
waiter_impl
*
impl
;
const
struct
waiter_impl
*
impl
;
VTAILQ_ENTRY
(
waiter
)
list
;
VTAILQ_ENTRY
(
waiter
)
list
;
VTAILQ_HEAD
(,
waited
)
waithead
;
int
dismantle
;
int
dismantle
;
waiter_handle_f
*
func
;
waiter_handle_f
*
func
;
int
pipes
[
2
];
struct
waited
*
pipe_w
;
double
next_idle
;
double
next_idle
;
int
do_pipe
;
volatile
double
*
tmo
;
volatile
double
*
tmo
;
VTAILQ_HEAD
(,
waited
)
waithead
;
void
*
priv
;
void
*
priv
;
};
};
typedef
void
waiter_init_f
(
struct
waiter
*
);
typedef
void
waiter_init_f
(
struct
waiter
*
);
typedef
void
waiter_fini_f
(
struct
waiter
*
);
typedef
void
waiter_fini_f
(
struct
waiter
*
);
typedef
int
waiter_
pass
_f
(
void
*
priv
,
struct
waited
*
);
typedef
int
waiter_
enter
_f
(
void
*
priv
,
struct
waited
*
);
typedef
void
waiter_inject_f
(
const
struct
waiter
*
,
struct
waited
*
);
typedef
void
waiter_inject_f
(
const
struct
waiter
*
,
struct
waited
*
);
typedef
void
waiter_evict_f
(
const
struct
waiter
*
,
struct
waited
*
);
typedef
void
waiter_evict_f
(
const
struct
waiter
*
,
struct
waited
*
);
...
@@ -61,16 +59,11 @@ struct waiter_impl {
...
@@ -61,16 +59,11 @@ struct waiter_impl {
const
char
*
name
;
const
char
*
name
;
waiter_init_f
*
init
;
waiter_init_f
*
init
;
waiter_fini_f
*
fini
;
waiter_fini_f
*
fini
;
waiter_
pass_f
*
pass
;
waiter_
enter_f
*
enter
;
waiter_inject_f
*
inject
;
waiter_inject_f
*
inject
;
waiter_evict_f
*
evict
;
size_t
size
;
size_t
size
;
};
};
/* cache_waiter.c */
void
Wait_Handle
(
struct
waiter
*
,
struct
waited
*
,
enum
wait_event
,
double
now
);
void
Wait_UsePipe
(
struct
waiter
*
w
);
/* mgt_waiter.c */
/* mgt_waiter.c */
extern
struct
waiter_impl
const
*
waiter
;
extern
struct
waiter_impl
const
*
waiter
;
...
...
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