apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Henry Jen <henry...@ztune.net>
Subject Re: Thread pool prototype
Date Mon, 01 May 2006 20:14:25 GMT
William A. Rowe, Jr. wrote:
> Henry Jen wrote:
>> Please let me know if you have any comments. :-)
>> +/**
>> + * Setup all of the internal structures required to use thread pools
>> + */
>> +APR_DECLARE(apr_status_t) apr_thread_pool_init(void);
>> +
>> +/**
>> + * Tear down all of the internal structures required to use pools
>> + */
>> +APR_DECLARE(void) apr_thread_pool_terminate(void);
> Double initialization, double teardown issues?  Consider that my libfoo.so
> may want to create a threadpool, I'm not privy to whether or not the 
> application
> that embedded libfoo.so actualy intialized the threadpool API itself.
> Is this needed?  If not can we please chuck it?  I understand the desire to
> anticipate the unanticipated, but this certainly will be a bigger 
> problem if
> it were used, than if we discover it's needed somehow.

Based on the implementation, it does not seem to be needed. I will take 
it out. So is the apr_thread_pool_task_t type definition. We can simply 
reuse the apr_thread_start_t.

As the multiple init/term, that would be carefully handled as 
apr_init/term if those function is actually in use. :-)

>> +APR_DECLARE(apr_thread_pool_t*) apr_thread_pool_create(apr_pool_t *pool,
>> +                                                       apr_size_t 
>> init_threads, +                                                       
>> apr_size_t max_threads, 
>> +                                                       apr_status_t 
>> *err);
> Do you mean
> APR_DECLARE(apr_status_t) apr_thread_pool_create(apr_thread_pool_t 
> **threadpool,
>                                                  apr_pool_t *pool,
>                                                  apr_size_t init_threads,
>                                                  apr_size_t max_threads);
> Please follow style guidelines, and precident, in your proposals :)

Is there a guideline other than 

I understand the precedent, but I thought there is no requirement. :-D
apr_hash_t * 	apr_hash_make (apr_pool_t *pool)

I prefer this way because it is clear that an app can check against the 
returned pointer to be NULL without worrying the value to be undefined 
when an error occurs.

That said, I will fix it.

>> +/**
>> + * Get current number of tasks waiting in the queue
>> + * @param me The thread pool
>> + * @return Number of tasks in the queue
>> + */
>> +APR_DECLARE(int) apr_thread_pool_tasks_cnt_get(apr_thread_pool_t *me);
> Worst of all worlds.  It's not a property (e.g. get/set), it's a verb 
> (please
> *count* for me your entities), so apr_thread_pool_tasks_count( ) seems 
> right.
>> +/**
>> + * Get current number of idling thread
>> + * @param me The thread pool
>> + * @return Number of idling threads
>> + */
>> +APR_DECLARE(int) apr_thread_pool_unused_cnt_get(apr_thread_pool_t *me);
> ditto... _count() not cnt_get()

Thank you! Pardon me as not a native English speaker.

>> +/**
>> + * Stop all unused threads. Ignore the maximum number of idling threads.
>> + * @param me The thread pool
>> + * @return The total number of threads stopped.
>> + */
>> +APR_DECLARE(int) 
>> apr_thread_pool_stop_unused_threads(apr_thread_pool_t *me);
> What's the difference between setting apr_thread_pool_unused_max_set() 
> to 0,
> and this function?  Can we drop it?
> It seems this function would stop idling threads at this point in time, 
> while
> it makes much more design sense to set unused_max to 0, ensuring the unused
> threads continue to be pruned as they finish their unit of work.
> Thoughts?

I tend to agree with you. Just use the set_unused_max makes sense.

In a way they work the same. But there are a few interesting differences:

1. Set the unused max does not force the thread to stop, an unused 
thread kills itself when it becomes idle and realize there are enough 
idle threads. Thus no joining or any locking issue for using this function.

2. stop_unused_threads kills *all* unused threads regardless the unused_max.

Is that mechanism make sense or just adding complexity? Not sure. It is 
for occasions you want to kill all unused threads and allow them to grow 
later. But why does an app do that? Under a resource constraint 
environment, this can serve as a mechanism for error recovery. Of 
course, you can do that with two consequent call to set_unused_max.

Think of that, I forgot to signal the idle threads when new tasks are 
added! :-P


View raw message