Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Joe Martin
OpenLDAP
Commits
81ead4a5
Commit
81ead4a5
authored
Jul 24, 2018
by
Ondřej Kuzník
Browse files
Fix races with backend_retry
parent
c0872442
Changes
1
Hide whitespace changes
Inline
Side-by-side
servers/lloadd/backend.c
View file @
81ead4a5
...
...
@@ -38,6 +38,12 @@ upstream_connect_cb( evutil_socket_t s, short what, void *arg )
Debug
(
LDAP_DEBUG_CONNS
,
"upstream_connect_cb: "
"fd=%d connection callback for backend uri='%s'
\n
"
,
s
,
b
->
b_uri
.
bv_val
);
if
(
s
!=
conn
->
fd
)
{
/* backend_reset has been here first */
goto
preempted
;
}
if
(
what
==
EV_WRITE
)
{
socklen_t
optlen
=
sizeof
(
error
);
...
...
@@ -74,9 +80,8 @@ done:
error
?
sock_errstr
(
error
,
ebuf
,
sizeof
(
ebuf
)
)
:
""
);
}
backend_retry
(
b
);
}
else
{
b
->
b_failed
=
0
;
}
preempted:
ldap_pvt_thread_mutex_unlock
(
&
b
->
b_mutex
);
event_free
(
conn
->
event
);
...
...
@@ -485,22 +490,39 @@ backend_connect_task( void *ctx, void *arg )
}
/*
* Needs exclusive access to the backend.
* Needs exclusive access to the backend and no other thread is allowed to call
* backend_retry while we're handling this.
*
* If gentle == 0, a full pause must be in effect, else we risk deadlocking on
* event_free().
*/
void
backend_reset
(
LloadBackend
*
b
,
int
gentle
)
{
if
(
b
->
b_cookie
)
{
int
rc
;
rc
=
ldap_pvt_thread_pool_retract
(
b
->
b_cookie
);
assert
(
rc
==
1
);
b
->
b_cookie
=
NULL
;
b
->
b_opening
--
;
if
(
ldap_pvt_thread_pool_retract
(
b
->
b_cookie
)
)
{
b
->
b_cookie
=
NULL
;
b
->
b_opening
--
;
}
else
{
/*
* The task might not be cancelable because it just started
* executing.
*
* Shutdown should be the only time when the thread pool is
* in that state. Keep the cookie in to keep an eye on whether
* it's finished yet.
*/
assert
(
slapd_shutdown
);
}
}
/* Not safe to hold our mutex and call event_del/free if the event's
* callback is running, relinquish the mutex while we do so. */
if
(
b
->
b_retry_event
&&
event_pending
(
b
->
b_retry_event
,
EV_TIMEOUT
,
NULL
)
)
{
assert
(
b
->
b_failed
);
ldap_pvt_thread_mutex_unlock
(
&
b
->
b_mutex
);
event_del
(
b
->
b_retry_event
);
ldap_pvt_thread_mutex_lock
(
&
b
->
b_mutex
);
b
->
b_opening
--
;
}
if
(
b
->
b_dns_req
)
{
...
...
@@ -515,16 +537,24 @@ backend_reset( LloadBackend *b, int gentle )
"destroying socket pending connect() fd=%d
\n
"
,
pending
->
fd
);
event_
fre
e
(
pending
->
event
);
event_
activ
e
(
pending
->
event
,
EV_WRITE
,
0
);
evutil_closesocket
(
pending
->
fd
);
pending
->
fd
=
-
1
;
LDAP_LIST_REMOVE
(
pending
,
next
);
ch_free
(
pending
);
if
(
!
gentle
)
{
/* None of the event bases are running, we're safe to free the
* event right now and potentially free the backend itself */
event_free
(
pending
->
event
);
ch_free
(
pending
);
}
/* else, just let the event dispose of the resources on its own later */
b
->
b_opening
--
;
}
connections_walk
(
&
b
->
b_mutex
,
&
b
->
b_preparing
,
lload_connection_close
,
&
gentle
);
assert
(
LDAP_CIRCLEQ_EMPTY
(
&
b
->
b_preparing
)
);
assert
(
b
->
b_opening
==
0
);
assert
(
b
->
b_opening
==
(
b
->
b_cookie
?
1
:
0
)
);
b
->
b_failed
=
0
;
connections_walk_last
(
&
b
->
b_mutex
,
&
b
->
b_bindconns
,
b
->
b_last_bindconn
,
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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