Re: custom background thread and module sharing a data structure

2009-03-13 Thread Andrej van der Zee
Hi,



> My point is that within a single process, multiple threads can service
> requests that can end up firing your module code. If you only do process
> locking you can still have more than 1 thread executing your module code at
> the same time.
>
> Just a process level lock will *not* guarantee that only a single thread is
> executing your code within the process holding the lock. A inter thread lock
> is needed to synchronize multiple threads within that processes from
> stomping on a shared resource.
>
>
Yeah you are right, two thread in the same process in the mpm worker model
still execute the same code to access the shared inter-process resource. So
I guess I need to add the thread-based mutexes within a APR_HAS_THREADS
define, like in some other modules I have seen. Thanks for clearing this up!

Cheers,
Andrej


Re: custom background thread and module sharing a data structure

2009-03-13 Thread Saju Pillai

Andrej van der Zee wrote:

Hi,

Thanks for your comments. See below...

Worker mpm is a multithreaded, multiprocess mpm. Multiple child processes

host multiple worker threads that run your module code.

If your module services 2 concurrent requests in 2 different threads in the
same process and both the threads need to access critical code at the same
time, you will have to use thread locking to prevent race conditions.



Yes, I understand the concept of mpm worker. My point was slightly
different: When I start a background thread in the post_config()-hook, it is
created in the address space of the server, and not of the processes that
run worker threads for handling HTTP requests. Therefore, threads that
handle HTTP requests always execute in a different process than the
background thread, and thus thread-based locking is not necessary for
sharing inter-process data.



My point is that within a single process, multiple threads can service 
requests that can end up firing your module code. If you only do process 
locking you can still have more than 1 thread executing your module code 
at the same time.


Just a process level lock will *not* guarantee that only a single thread 
is executing your code within the process holding the lock. A inter 
thread lock is needed to synchronize multiple threads within that 
processes from stomping on a shared resource.



srp
--
http://saju.net.in


Re: post_config on reload

2009-03-13 Thread Andrej van der Zee
Hi,


Register a function with the cleanup of the conf pool. The conf pool
>> is destroyed prior to a restart/kill/reload.
>>
>> You have an example in the code I've sent you.
>>
>> S
>>
>>
>>
> Perfect answer!  Unfortunately, the post_config is called twice on a
> restart, and with different memory pointers, so shared memory handles,
> mutexes, etc, those will all suddenly disappear.  You'd be forced to
> initialize your post_config again or potentially segmentation fault the
> server.  So, that is a good excuse to implement some extra code to handle
> restarting a thread anyway.
>
>
Thanks, one less choice to make :)

Greets,
Andrej


Re: custom background thread and module sharing a data structure

2009-03-13 Thread Andrej van der Zee
Hi,

Thanks for your comments. See below...

Worker mpm is a multithreaded, multiprocess mpm. Multiple child processes
> host multiple worker threads that run your module code.
>
> If your module services 2 concurrent requests in 2 different threads in the
> same process and both the threads need to access critical code at the same
> time, you will have to use thread locking to prevent race conditions.


Yes, I understand the concept of mpm worker. My point was slightly
different: When I start a background thread in the post_config()-hook, it is
created in the address space of the server, and not of the processes that
run worker threads for handling HTTP requests. Therefore, threads that
handle HTTP requests always execute in a different process than the
background thread, and thus thread-based locking is not necessary for
sharing inter-process data.

re: Using non APR locking mechanisms - sure they will work as long as you
> are using compatible mechanisms (like if apr_threads is based on pthreads,
> the alternate locking mechanism should work with pthreads).
>

That's good news!

Cheers,
Andrej


Re: post_config on reload

2009-03-13 Thread Joe Lewis

Sorin Manolache wrote:

On Fri, Mar 13, 2009 at 16:21, Andrej van der Zee
 wrote:
  

Hi,

Do not do this -  a restart should be a restart, not a half of a restart.


 You should be reinitializing whatever you do on a restart as well as a
start.  That's the whole point.

I have one phrase that should illustrate why : memory leak.

For example, if your extension creates another thread or spawns another
process and that other thread/process doesn't clean up on a restart and
contains a memory leak, what good is restart to you? Restart has suddenly
become pointless.

It is good etiquette to honour the concept of a restart.

  

Okay, point taken. My extension indeed creates a thread. How can I know that
a user issues a restart? In other words, where can I kill my thread?



Register a function with the cleanup of the conf pool. The conf pool
is destroyed prior to a restart/kill/reload.

You have an example in the code I've sent you.

S

  
Perfect answer!  Unfortunately, the post_config is called twice on a 
restart, and with different memory pointers, so shared memory handles, 
mutexes, etc, those will all suddenly disappear.  You'd be forced to 
initialize your post_config again or potentially segmentation fault the 
server.  So, that is a good excuse to implement some extra code to 
handle restarting a thread anyway.


Joe


Re: custom background thread and module sharing a data structure

2009-03-13 Thread Saju Pillai

Andrej van der Zee wrote:

Hi Saju,

For the worker mpm, both cross thread and cross process protection will be

needed. apr_proc_mutex.h family supplies cross-process protection,
apr_thread_mutex.h provides cross thread protection.

You "locking" method would be a wrapper method that first obtains a process
level lock, and then inside that lock it obtains a thread level lock.



In my specific case, do I really need thread-level locking in addition to
process-level locking? Since I am running a background thread that is
started in post_config(), worker-threads in the mpm worker model are running
in a different process then my background thread anyway. So I guess
process-level locking should suffice, or am I overlooking something?


Worker mpm is a multithreaded, multiprocess mpm. Multiple child 
processes host multiple worker threads that run your module code.


If your module services 2 concurrent requests in 2 different threads in 
the same process and both the threads need to access critical code at 
the same time, you will have to use thread locking to prevent race 
conditions.


re: Using non APR locking mechanisms - sure they will work as long as 
you are using compatible mechanisms (like if apr_threads is based on 
pthreads, the alternate locking mechanism should work with pthreads).



srp
--
http://saju.net.in


Re: post_config on reload

2009-03-13 Thread Andrej van der Zee
Hi,

Do not do this -  a restart should be a restart, not a half of a restart.
>  You should be reinitializing whatever you do on a restart as well as a
> start.  That's the whole point.
>
> I have one phrase that should illustrate why : memory leak.
>
> For example, if your extension creates another thread or spawns another
> process and that other thread/process doesn't clean up on a restart and
> contains a memory leak, what good is restart to you? Restart has suddenly
> become pointless.
>
> It is good etiquette to honour the concept of a restart.
>

Okay, point taken. My extension indeed creates a thread. How can I know that
a user issues a restart? In other words, where can I kill my thread?

Cheers,
Andrej


Re: post_config on reload

2009-03-13 Thread Sorin Manolache
On Fri, Mar 13, 2009 at 16:21, Andrej van der Zee
 wrote:
> Hi,
>
> Do not do this -  a restart should be a restart, not a half of a restart.
>>  You should be reinitializing whatever you do on a restart as well as a
>> start.  That's the whole point.
>>
>> I have one phrase that should illustrate why : memory leak.
>>
>> For example, if your extension creates another thread or spawns another
>> process and that other thread/process doesn't clean up on a restart and
>> contains a memory leak, what good is restart to you? Restart has suddenly
>> become pointless.
>>
>> It is good etiquette to honour the concept of a restart.
>>
>
> Okay, point taken. My extension indeed creates a thread. How can I know that
> a user issues a restart? In other words, where can I kill my thread?

Register a function with the cleanup of the conf pool. The conf pool
is destroyed prior to a restart/kill/reload.

You have an example in the code I've sent you.

S

-- 
A: Because it reverses the logical flow of conversation.
Q: Why is top-posting frowned upon?
A: Top-posting.
Q: What is the most annoying thing in e-mail?


Re: custom background thread and module sharing a data structure

2009-03-13 Thread Andrej van der Zee
Hi Saju,

For the worker mpm, both cross thread and cross process protection will be
> needed. apr_proc_mutex.h family supplies cross-process protection,
> apr_thread_mutex.h provides cross thread protection.
>
> You "locking" method would be a wrapper method that first obtains a process
> level lock, and then inside that lock it obtains a thread level lock.
>

In my specific case, do I really need thread-level locking in addition to
process-level locking? Since I am running a background thread that is
started in post_config(), worker-threads in the mpm worker model are running
in a different process then my background thread anyway. So I guess
process-level locking should suffice, or am I overlooking something?

Thank you,
Andrej


post_config on reload

2009-03-13 Thread Andrej van der Zee
Hi,

I found this piece of code for dealing with the post_config issue (it is
called twice, while I need to initialise my stuff only once):

  void *data;
  const char *userdata_key = "post_config_only_once_key";
  apr_pool_userdata_get(&data, userdata_key, s->process->pool);
  if (!data) {
apr_pool_userdata_set((const void *)1, userdata_key,
apr_pool_cleanup_null, s->process->pool);
return OK;
  } else {
 // do initialize
  }

I was wondering if there is a solution for detecting a post_config
invocation on behalf of "apachctl restart" instead of a clean start (in case
of a restart, I do not want to initialise my stuff again).

Thank you,
Andrej