Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
openldap
OpenLDAP
Commits
3e90c7dd
Commit
3e90c7dd
authored
Dec 31, 2001
by
Howard Chu
Browse files
Use queue-compat.h for queue management. Cache ctx structures on a free
list instead of always freeing them.
parent
b7be0228
Changes
1
Hide whitespace changes
Inline
Side-by-side
libraries/libldap_r/tpool.c
View file @
3e90c7dd
...
...
@@ -20,6 +20,7 @@
#include
"ldap-int.h"
#include
"ldap_pvt_thread.h"
#include
"queue-compat.h"
#ifndef LDAP_THREAD_HAVE_TPOOL
...
...
@@ -29,15 +30,20 @@ enum ldap_int_thread_pool_state {
LDAP_INT_THREAD_POOL_STOPPING
};
typedef
struct
ldap_int_thread_list_element_s
{
struct
ldap_int_thread_list_element_s
*
next
;
}
ldap_int_thread_list_element_t
,
*
ldap_int_thread_list_t
;
typedef
struct
ldap_int_thread_ctx_s
{
union
{
SLIST_ENTRY
(
ldap_int_thread_ctx_s
)
l
;
STAILQ_ENTRY
(
ldap_int_thread_ctx_s
)
q
;
}
ltc_next
;
void
*
(
*
ltc_start_routine
)(
void
*
);
void
*
ltc_arg
;
}
ldap_int_thread_ctx_t
;
struct
ldap_int_thread_pool_s
{
struct
ldap_int_thread_pool_s
*
ltp_next
;
STAILQ_ENTRY
(
ldap_int_thread_pool_s
)
ltp_next
;
ldap_pvt_thread_mutex_t
ltp_mutex
;
ldap_pvt_thread_cond_t
ltp_cond
;
ldap_int_thread_
list_t
ltp_pending_list
;
STAILQ_HEAD
(
tcq
,
ldap_int_thread_
ctx_s
)
ltp_pending_list
;
long
ltp_state
;
long
ltp_max_count
;
long
ltp_max_pending
;
...
...
@@ -47,39 +53,44 @@ struct ldap_int_thread_pool_s {
long
ltp_starting
;
};
typedef
struct
ldap_int_thread_ctx_s
{
struct
ldap_int_thread_ctx_s
*
ltc_next
;
void
*
(
*
ltc_start_routine
)(
void
*
);
void
*
ltc_arg
;
}
ldap_int_thread_ctx_t
;
static
STAILQ_HEAD
(
tpq
,
ldap_int_thread_pool_s
)
ldap_int_thread_pool_list
=
STAILQ_HEAD_INITIALIZER
(
ldap_int_thread_pool_list
);
static
SLIST_HEAD
(
tcl
,
ldap_int_thread_ctx_s
)
ldap_int_ctx_free_list
=
SLIST_HEAD_INITIALIZER
(
ldap_int_ctx_free_list
);
static
ldap_int_thread_list_t
ldap_int_thread_pool_list
=
NULL
;
static
ldap_pvt_thread_mutex_t
ldap_pvt_thread_pool_mutex
;
static
ldap_pvt_thread_mutex_t
ldap_pvt_ctx_free_mutex
;
static
void
*
ldap_int_thread_pool_wrapper
(
struct
ldap_int_thread_pool_s
*
pool
);
static
void
*
ldap_int_thread_enlist
(
ldap_int_thread_list_t
*
list
,
void
*
elem
);
static
void
*
ldap_int_thread_delist
(
ldap_int_thread_list_t
*
list
,
void
*
elem
);
#if 0
static void *ldap_int_thread_onlist( ldap_int_thread_list_t *list, void *elem );
#endif
int
ldap_int_thread_pool_startup
(
void
)
{
return
ldap_pvt_thread_mutex_init
(
&
ldap_pvt_thread_pool_mutex
);
int
rc
=
ldap_pvt_thread_mutex_init
(
&
ldap_pvt_thread_pool_mutex
);
if
(
rc
==
0
)
rc
=
ldap_pvt_thread_mutex_init
(
&
ldap_pvt_ctx_free_mutex
);
return
rc
;
}
int
ldap_int_thread_pool_shutdown
(
void
)
{
while
(
ldap_int_thread_pool_list
!=
NULL
)
{
struct
ldap_int_thread_pool_s
*
pool
=
(
struct
ldap_int_thread_pool_s
*
)
ldap_int_thread_pool_list
;
ldap_int_thread_ctx_t
*
ctx
;
struct
ldap_int_thread_pool_s
*
pool
;
while
((
pool
=
STAILQ_FIRST
(
&
ldap_int_thread_pool_list
))
!=
NULL
)
{
STAILQ_REMOVE_HEAD
(
&
ldap_int_thread_pool_list
,
ltp_next
);
ldap_pvt_thread_pool_destroy
(
&
pool
,
0
);
}
while
((
ctx
=
SLIST_FIRST
(
&
ldap_int_ctx_free_list
)))
{
SLIST_REMOVE_HEAD
(
&
ldap_int_ctx_free_list
,
ltc_next
.
l
);
free
(
ctx
);
}
ldap_pvt_thread_mutex_destroy
(
&
ldap_pvt_ctx_free_mutex
);
ldap_pvt_thread_mutex_destroy
(
&
ldap_pvt_thread_pool_mutex
);
return
(
0
);
}
...
...
@@ -109,7 +120,11 @@ ldap_pvt_thread_pool_init (
pool
->
ltp_max_count
=
max_threads
;
pool
->
ltp_max_pending
=
max_pending
;
ldap_pvt_thread_mutex_lock
(
&
ldap_pvt_thread_pool_mutex
);
ldap_int_thread_enlist
(
&
ldap_int_thread_pool_list
,
pool
);
if
(
STAILQ_EMPTY
(
&
ldap_int_thread_pool_list
))
{
STAILQ_INSERT_HEAD
(
&
ldap_int_thread_pool_list
,
pool
,
ltp_next
);
}
else
{
STAILQ_INSERT_TAIL
(
&
ldap_int_thread_pool_list
,
pool
,
ltp_next
);
}
ldap_pvt_thread_mutex_unlock
(
&
ldap_pvt_thread_pool_mutex
);
#if 0
...
...
@@ -136,7 +151,8 @@ ldap_pvt_thread_pool_init (
if( rc != 0) {
/* couldn't start one? then don't start any */
ldap_pvt_thread_mutex_lock(&ldap_pvt_thread_pool_mutex);
ldap_int_thread_delist(&ldap_int_thread_pool_list, pool);
STAILQ_REMOVE(ldap_int_thread_pool_list, pool,
ldap_int_thread_element_s, ltp_next);
ldap_pvt_thread_mutex_unlock(&ldap_pvt_thread_pool_mutex);
ldap_pvt_thread_cond_destroy(&pool->ltp_cond);
ldap_pvt_thread_mutex_destroy(&pool->ltp_mutex);
...
...
@@ -167,25 +183,38 @@ ldap_pvt_thread_pool_submit (
if
(
pool
==
NULL
)
return
(
-
1
);
ctx
=
(
ldap_int_thread_ctx_t
*
)
LDAP_CALLOC
(
1
,
sizeof
(
ldap_int_thread_ctx_t
));
if
(
ctx
==
NULL
)
return
(
-
1
);
ctx
->
ltc_start_routine
=
start_routine
;
ctx
->
ltc_arg
=
arg
;
ldap_pvt_thread_mutex_lock
(
&
pool
->
ltp_mutex
);
if
(
pool
->
ltp_state
!=
LDAP_INT_THREAD_POOL_RUNNING
||
(
pool
->
ltp_max_pending
>
0
&&
pool
->
ltp_pending_count
>=
pool
->
ltp_max_pending
))
{
ldap_pvt_thread_mutex_unlock
(
&
pool
->
ltp_mutex
);
free
(
ctx
);
return
(
-
1
);
}
ldap_pvt_thread_mutex_lock
(
&
ldap_pvt_ctx_free_mutex
);
ctx
=
SLIST_FIRST
(
&
ldap_int_ctx_free_list
);
if
(
ctx
)
{
SLIST_REMOVE_HEAD
(
&
ldap_int_ctx_free_list
,
ltc_next
.
l
);
ldap_pvt_thread_mutex_unlock
(
&
ldap_pvt_ctx_free_mutex
);
}
else
{
ldap_pvt_thread_mutex_unlock
(
&
ldap_pvt_ctx_free_mutex
);
ctx
=
(
ldap_int_thread_ctx_t
*
)
LDAP_MALLOC
(
sizeof
(
ldap_int_thread_ctx_t
));
if
(
ctx
==
NULL
)
{
ldap_pvt_thread_mutex_unlock
(
&
pool
->
ltp_mutex
);
return
(
-
1
);
}
}
ctx
->
ltc_start_routine
=
start_routine
;
ctx
->
ltc_arg
=
arg
;
pool
->
ltp_pending_count
++
;
ldap_int_thread_enlist
(
&
pool
->
ltp_pending_list
,
ctx
);
if
(
STAILQ_EMPTY
(
&
pool
->
ltp_pending_list
))
{
STAILQ_INSERT_HEAD
(
&
pool
->
ltp_pending_list
,
ctx
,
ltc_next
.
q
);
}
else
{
STAILQ_INSERT_TAIL
(
&
pool
->
ltp_pending_list
,
ctx
,
ltc_next
.
q
);
}
ldap_pvt_thread_cond_signal
(
&
pool
->
ltp_cond
);
if
((
pool
->
ltp_open_count
<=
0
||
pool
->
ltp_pending_count
>
1
...
...
@@ -214,11 +243,16 @@ ldap_pvt_thread_pool_submit (
if
(
pool
->
ltp_open_count
==
0
)
{
/* no open threads at all?!?
*/
if
(
ldap_int_thread_delist
(
&
pool
->
ltp_pending_list
,
ctx
))
{
ldap_int_thread_ctx_t
*
ptr
;
STAILQ_FOREACH
(
ptr
,
&
pool
->
ltp_pending_list
,
ltc_next
.
q
)
if
(
ptr
==
ctx
)
break
;
if
(
ptr
==
ctx
)
{
/* no open threads, context not handled, so
* back out of ltp_pending_count, free the context,
* report the error.
*/
STAILQ_REMOVE
(
&
pool
->
ltp_pending_list
,
ctx
,
ldap_int_thread_ctx_s
,
ltc_next
.
q
);
pool
->
ltp_pending_count
++
;
ldap_pvt_thread_mutex_unlock
(
&
pool
->
ltp_mutex
);
free
(
ctx
);
...
...
@@ -279,7 +313,7 @@ ldap_pvt_thread_pool_backload ( ldap_pvt_thread_pool_t *tpool )
int
ldap_pvt_thread_pool_destroy
(
ldap_pvt_thread_pool_t
*
tpool
,
int
run_pending
)
{
struct
ldap_int_thread_pool_s
*
pool
;
struct
ldap_int_thread_pool_s
*
pool
,
*
pptr
;
long
waiting
;
ldap_int_thread_ctx_t
*
ctx
;
...
...
@@ -291,10 +325,14 @@ ldap_pvt_thread_pool_destroy ( ldap_pvt_thread_pool_t *tpool, int run_pending )
if
(
pool
==
NULL
)
return
(
-
1
);
ldap_pvt_thread_mutex_lock
(
&
ldap_pvt_thread_pool_mutex
);
pool
=
ldap_int_thread_delist
(
&
ldap_int_thread_pool_list
,
pool
);
STAILQ_FOREACH
(
pptr
,
&
ldap_int_thread_pool_list
,
ltp_next
)
if
(
pptr
==
pool
)
break
;
if
(
pptr
==
pool
)
STAILQ_REMOVE
(
&
ldap_int_thread_pool_list
,
pool
,
ldap_int_thread_pool_s
,
ltp_next
);
ldap_pvt_thread_mutex_unlock
(
&
ldap_pvt_thread_pool_mutex
);
if
(
pool
=
=
NULL
)
return
(
-
1
);
if
(
pool
!
=
pptr
)
return
(
-
1
);
ldap_pvt_thread_mutex_lock
(
&
pool
->
ltp_mutex
);
pool
->
ltp_state
=
run_pending
...
...
@@ -317,9 +355,9 @@ ldap_pvt_thread_pool_destroy ( ldap_pvt_thread_pool_t *tpool, int run_pending )
ldap_pvt_thread_mutex_unlock
(
&
pool
->
ltp_mutex
);
}
while
(
waiting
>
0
);
while
((
ctx
=
(
ldap_int_thread_ctx_t
*
)
ldap_int_thread_delist
(
&
pool
->
ltp_pending_list
,
NULL
))
!=
NULL
)
while
((
ctx
=
STAILQ_FIRST
(
&
pool
->
ltp_pending_list
))
!=
NULL
)
{
STAILQ_REMOVE_HEAD
(
&
pool
->
ltp_pending_list
,
ltc_next
.
q
);
free
(
ctx
);
}
...
...
@@ -341,9 +379,10 @@ ldap_int_thread_pool_wrapper (
ldap_pvt_thread_mutex_lock
(
&
pool
->
ltp_mutex
);
while
(
pool
->
ltp_state
!=
LDAP_INT_THREAD_POOL_STOPPING
)
{
ctx
=
ldap_int_thread_delist
(
&
pool
->
ltp_pending_list
,
NULL
);
if
(
ctx
==
NULL
)
{
ctx
=
STAILQ_FIRST
(
&
pool
->
ltp_pending_list
);
if
(
ctx
)
{
STAILQ_REMOVE_HEAD
(
&
pool
->
ltp_pending_list
,
ltc_next
.
q
);
}
else
{
if
(
pool
->
ltp_state
==
LDAP_INT_THREAD_POOL_FINISHING
)
break
;
if
(
pool
->
ltp_max_count
>
0
...
...
@@ -377,7 +416,9 @@ ldap_int_thread_pool_wrapper (
ldap_pvt_thread_mutex_unlock
(
&
pool
->
ltp_mutex
);
(
ctx
->
ltc_start_routine
)(
ctx
->
ltc_arg
);
free
(
ctx
);
ldap_pvt_thread_mutex_lock
(
&
ldap_pvt_ctx_free_mutex
);
SLIST_INSERT_HEAD
(
&
ldap_int_ctx_free_list
,
ctx
,
ltc_next
.
l
);
ldap_pvt_thread_mutex_unlock
(
&
ldap_pvt_ctx_free_mutex
);
ldap_pvt_thread_yield
();
/* if we use an idle timer, here's
...
...
@@ -394,61 +435,4 @@ ldap_int_thread_pool_wrapper (
ldap_pvt_thread_exit
(
NULL
);
return
(
NULL
);
}
static
void
*
ldap_int_thread_enlist
(
ldap_int_thread_list_t
*
list
,
void
*
elem
)
{
ldap_int_thread_list_element_t
*
prev
;
if
(
elem
==
NULL
)
return
(
NULL
);
((
ldap_int_thread_list_element_t
*
)
elem
)
->
next
=
NULL
;
if
(
*
list
==
NULL
)
{
*
list
=
elem
;
return
(
elem
);
}
for
(
prev
=
*
list
;
prev
->
next
!=
NULL
;
prev
=
prev
->
next
)
;
prev
->
next
=
elem
;
return
(
elem
);
}
static
void
*
ldap_int_thread_delist
(
ldap_int_thread_list_t
*
list
,
void
*
elem
)
{
ldap_int_thread_list_element_t
*
prev
;
if
(
*
list
==
NULL
)
return
(
NULL
);
if
(
elem
==
NULL
)
elem
=
*
list
;
if
(
*
list
==
elem
)
{
*
list
=
((
ldap_int_thread_list_element_t
*
)
elem
)
->
next
;
return
(
elem
);
}
for
(
prev
=
*
list
;
prev
->
next
!=
NULL
;
prev
=
prev
->
next
)
{
if
(
prev
->
next
==
elem
)
{
prev
->
next
=
((
ldap_int_thread_list_element_t
*
)
elem
)
->
next
;
return
(
elem
);
}
}
return
(
NULL
);
}
#if 0
static void *
ldap_int_thread_onlist( ldap_int_thread_list_t *list, void *elem )
{
ldap_int_thread_list_element_t *prev;
if (elem == NULL || *list == NULL) return(NULL);
for (prev = *list ; prev != NULL; prev = prev->next) {
if (prev == elem)
return(elem);
}
return(NULL);
}
#endif
#endif
/* LDAP_HAVE_THREAD_POOL */
Write
Preview
Supports
Markdown
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