Re: timer behaviour

2011-06-14 Thread com...@gmx.ch

On 06/13/2011 11:23 PM, Juan Pablo L wrote:

attached is source for database pool module,


Besides from the locking issues outlined here, you are doing it wrong.
You can run a postgres database connection completely nonblocking, 
without threads.
While it is not easy to get things right the first time - better read 
the docs twice, it is much easier to use the nonblocking interface than 
dealing with threads  mutexes.


If the database-con is busy, queue the request, if the database-con is 
available run a request from the queue, if the database-con wants to 
read, EV_READ, if the database-con wants to write, EV_WRITE to the 
appropriate callback.
Give each request a callback to report the result, call the callback 
once the query is done and block issuing new requests on the 
database-con during while the callback is running.


As there is very little computation required on the client side of a 
database connection you do not need threads anyway, and not having 
mutexes is likely to make the code easier and more scalable therefore.



___
libev mailing list
libev@lists.schmorp.de
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev


Re: ev_is_active - at which point?

2010-06-02 Thread com...@gmx.ch

Marc Lehmann wrote:

On Wed, May 26, 2010 at 12:01:28AM +0200, com...@gmx.ch com...@gmx.ch wrote:
But, ev_is_active reports the timer is not active, I do not disable the  
timer, and the timers callback gets fired afterwards.


That's as documented (see ev_TYPE_start/stop, ev_is_active and
ev_is_pending).


Thats the problem.


Maybe, but you need to explain why that is a problem?



Not reading the docs properly was the problem.


Markus

___
libev mailing list
libev@lists.schmorp.de
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev


ev_is_active - at which point?

2010-05-25 Thread com...@gmx.ch

Hi,

I got the following problem with ev_is_active():

I got a ev_timer, and it gets started, then something which takes a lot 
of time happens, and I'd stop the timer if ev_is_active claims the timer 
is still active.
But, ev_is_active reports the timer is not active, I do not disable the 
timer, and the timers callback gets fired afterwards.


Thats the problem.
ev_is_active reports the timer is inactive, and the callback gets fired.
Sounds scary, yes.

I used gdb to verify:

ev_is_active is false:

(gdb) p con-events.dns_timeout
$6 = {active = 0, pending = 1, priority = 0, data = 0x9a2b8c8, cb = 
0x805a410 the_cb,

  at = -3.4154873266816139, repeat = 0}

but later on, the callback fires:

(gdb) p con-events.dns_timeout
$7 = {active = 0, pending = 0, priority = 0, data = 0x9a2b8c8, cb = 
0x805a410 the_cb,

  at = -3.4154873266816139, repeat = 0}

I noticed the 'pending' field, so when is a not repeating ev_timer inactive?
If I ask to disable an ev_timer in the same ev_loop iteration which 
would fire the callback (ev_timer.pending = 1), is the 
ev_is_active(ev_timer) meant to be true or false?


I'd expect it to be true - as I did not call ev_timer_stop on it yet, 
and the callback did not come in yet, but I think I'm wrong.


Attached is a sample program, t1_cb is expected to stop t2, so t2_cb 
never gets called, but t2_cb is called always.


./timertest
called t1_cb loop 0x7fd720899200 w 0x601100 revents 256
called t2_cb loop 0x7fd720899200 w 0x601080 revents 256



Thanks,
Markus
/*
gcc -Wall -o timertest timertest.c -lev
*/

#include stdio.h
#include unistd.h
#include ev.h
#include time.h

struct ev_timer t1;
struct ev_timer t2;
struct ev_signal s1;

void waste(time_t s)
{
	time_t now = time(NULL);
	int i = 0;
	while((now + s)  time(NULL))
		i++;
}
	

void t1_cb(struct ev_loop *loop, struct ev_timer *w, int revents)
{
	printf(called %s loop %p w %p revents %i\n, __PRETTY_FUNCTION__, loop, w, revents);	
	if( ev_is_active(t2) )
	{
		printf(stopping t2\n);
		ev_timer_stop(loop, t2);
	}
}

void t2_cb(struct ev_loop *loop, struct ev_timer *w, int revents)
{
	printf(called %s loop %p w %p revents %i\n, __PRETTY_FUNCTION__, loop, w, revents);
}

int main()
{
	struct ev_loop *loop = ev_default_loop (0);
	ev_timer_init(t1, t1_cb, 1.0, 0);
	ev_timer_init(t2, t2_cb, 5.0, 0); 
	ev_timer_start(loop, t1);
	ev_timer_start(loop, t2);	
	waste(6);
	ev_loop (loop, 0);
	return 0;
}
___
libev mailing list
libev@lists.schmorp.de
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev

Re: [ANN] x0 HTTP server and framework (initial release)

2010-04-03 Thread com...@gmx.ch

Marc Lehmann wrote:

On Thu, Apr 01, 2010 at 10:53:39AM +0200, Graham Leggett minf...@sharp.fm 
wrote:
You might be tempted to keep two socket watchers going for listening to 
socket read events, and socket write events, but to support SSL  


This is the mess how it is commonly implemented, and it is indeed horrors.


I've had the non-blocking ssl challenge too, and I use two socket 
watchers, I know it can be done using a single watcher, but ... I'd call 
it a tradeoff, using two io watchers simplified the code and therefore I 
decided to take the performance impact into account.


In fact, given the possibility, I use two io watchers for every type of 
connection, even tcp and udp, and a multitude of timers for each 
connection type to provide timeouts for all kinds of things I want to be 
able to deal with (idle, sustain, listen, throtte_(in,out), connecting, 
dnsresolve, close, handshake, reconnect).


This makes a total of
 * 2 io watchers
 * 10 timers
- 12 watchers per connection

where 1 io watcher (in) and 2 timers (idlesustain) are active most of 
the time.


I'm totally aware could be done with 2 watchers, one for io, and one 
timeout and some internal list to have only the 'next' timeout active in 
libev, but I don't feel bad about it.


In fact, libev performs that great, I did not even notice a when it had 
about 6000 connections.


So, if you don't need the extra tidbit of performance, you can keep 
things simple.



A much easier way is to decouple openssl from the socket altogether,
i.e. don't let it do socket I/O, instead let it do I/O from/two two
BIO buffers, which simplifies things a lot - no need to watch for
SSL_WANT_READ and other issues, no need to switch watcher state based on
return codes etc.



As you have to call SSL_write again with the same arguments again if you 
get a SSL_WANT_* error, you need two write queues, so you can provide 
the same arguments.


I was looking for rate limiting, and therefore I calculate how much I'm 
allowed to read/write.
To prevent reading/writing too small chunks, I allow reading/writing 
some bytes more - the amount is calculated relative to the allowed speed 
and already sent data for the sliding window-, and suspend the 
read/write io watchers in case I read/write to much, and use timers to 
wake up again.


As there are many ways to use non-blocking openssl in a wrong way, I'm 
glad it works.


Proper openssl shutdown was a real problem to me, as it did not work at 
all, turned out the problem was within openssl, and got patched in 0.9.8m.


I was looking at using BIOs myself, but I was not sure about rate 
limiting when using bios, and there is 'little' examples/documentation, 
besides some ascii image to illustrate how to design openssl nonblocking 
with bios.



I wanted to make a C example for quite some time, but didn't get to it
yet.


I saw libevent2 providing (rate limited) non-blocking openssl, but I'd 
say there is some (more) feature creep in libevent2, which makes it 
(even) less attractive to me.
Not even talking about performance - I got no numbers on libevent2, I 
prefer a simple api over features (I do not need in most cases).


But example code for (maybe even rate limited?) nonblocking ssl with 
bios on top of libev would be great.



___
libev mailing list
libev@lists.schmorp.de
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev


Re: problem with poll_poll() under FreeBSD

2010-03-29 Thread com...@gmx.ch

Zajcev Evgeny wrote:

as it was predicted, FreeBSD's poll() returned incorrect value :(.
I've skimed poll() implementation in FreeBSD and did not found any
place that can give such results, it might be due to lack of
knowledge.  I'll try to contact freebsd community..


The bug is obviously known - at least it was reported already:
http://forums.freebsd.org/showthread.php?t=10270

___
libev mailing list
libev@lists.schmorp.de
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev


Re: Optimal multithread model

2010-03-15 Thread com...@gmx.ch

I have something similar, therefore how I did it.

All polling is done by libev in the main-loop, a single main loop.
If a connection is established and processing the data needs some time, 
I remove the watchers from the loop, and creates a task from the data to 
process and the function to process the data, and pushes this set to an 
glib thread pool.


The thread is allowed calls the function to process the data with the 
data as argument, once it is done, it creates its result set, the data 
and a function which will deal with the result-data, and pushes this set 
to an async queue.
To signal libev there is something in the async queue, I use ev_async 
from the thread.


libev catches the ev_async, I remove all pending sets from the async 
queue, call the provided function with the data provided.
The function provided can rearm the watchers for the loop, and continue 
in the main loop.


It's rather simple, but works as expected.


Markus

___
libev mailing list
libev@lists.schmorp.de
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev


Re: [PATCH 2] fix broken strict aliasing

2010-02-24 Thread com...@gmx.ch

Hi,

Marc Lehmann wrote:

If you are unclear on what aliasing itself means, I can write a short
paragraph to explain...

(the iso c documents ae not that hard to read, though, imho, with the
exception of structure member aliasing).


I've had the same discussion before, but just pulled my claim as Marc 
was involved in gcc development, and I did not feel I could make a point.


I've had the same problems, -Wall -Werror, as I consider the compiler my 
friend and if he wants to tell me something it usually pays of when I'm 
listening to him.


But, I totally understand if Marc says it is not a libev bug, and 
rejects to add casts to proper code - to fix compiler misbehavior.


Therefore I'd be glad to get more information on the topic.
Thanks for the offer.


Markus

___
libev mailing list
libev@lists.schmorp.de
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev


Re: libev 3.8 threads signals

2009-09-25 Thread com...@gmx.ch

Marc Lehmann wrote:

On Thu, Sep 24, 2009 at 03:31:30PM +0200, com...@gmx.ch com...@gmx.ch wrote:

I have a g_thread_pool and libev, following pseudocode


I don't know what g_thread_pool does, but if it messes with the signal
mask, then it should just not do that, at elast not for signals you register
with libev.

libev (just like any other event loop) requires you to not touch resources
it manages, which includes SIGCHLD and any signal handler you install via it.

If something else in your program messes with those signals in any way, then
either that part is broken, or the part that installs the signal watcher in
libev.

These resources are simply nto sharable, as much as we'd like them to be.
Only one can manage it, which is why libev allows you to multiplex all
those signals.



You are right, g_thread_pool messes up the signals.

rt_sigprocmask(SIG_BLOCK, [INT CHLD], NULL, 8) = 0
syscall_289(0x5, 0x7fbf0d0606b0, 0x8, 0, 0x98, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) = 0x5

rt_sigprocmask(SIG_BLOCK, [HUP INT CHLD], NULL, 8) = 0
syscall_289(0x5, 0x7fbf0d0606b0, 0x8, 0, 0x5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) = 0x5


Thanks for reply.

Markus

___
libev mailing list
libev@lists.schmorp.de
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev


Re: libev 3.8 threads signals

2009-09-25 Thread com...@gmx.ch

You are right, g_thread_pool messes up the signals.

rt_sigprocmask(SIG_BLOCK, [INT CHLD], NULL, 8) = 0
syscall_289(0x5, 0x7fbf0d0606b0, 0x8, 0, 0x98, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) = 0x5

rt_sigprocmask(SIG_BLOCK, [HUP INT CHLD], NULL, 8) = 0
syscall_289(0x5, 0x7fbf0d0606b0, 0x8, 0, 0x5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) = 0x5


Hrm, further invesigation shows that was libev signal handler code ...
The glib thing does not touch signal handler the signal handler directly:

mmap(NULL, 8392704, PROT_READ|PROT_WRITE|PROT_EXEC, 
MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7f04a18e7000

mprotect(0x7f04a18e7000, 4096, PROT_NONE) = 0
clone(child_stack=0x7f04a20e7250, 
flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, 
parent_tidptr=0x7f04a20e79e0, tls=0x7f04a20e7950, 
child_tidptr=0x7f04a20e79e0) = 27442

futex(0x24d5b90, FUTEX_WAKE_PRIVATE, 1) = 1

maybe the CLONE_SIGHAND got something to do with it?

As mentioned before, this worked fine with libev 3.6.

Markus

___
libev mailing list
libev@lists.schmorp.de
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev


Re: libev 3.8 threads signals

2009-09-25 Thread com...@gmx.ch

Marc Lehmann wrote:

On Thu, Sep 24, 2009 at 04:46:42PM +0200, com...@gmx.ch com...@gmx.ch wrote:

Besides, why does the list reply to user per default?


Excuse the incorrect question, should have been
is the reply-to header missing by design for the list?

Markus

___
libev mailing list
libev@lists.schmorp.de
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev


Re: libev 3.8 threads signals

2009-09-24 Thread com...@gmx.ch

Luca Barbato wrote:

How is broken exactly? I'm tracking some yet another strange issues in
feng that cropped up recently and I'm using thread pools and libev
signal handlers as well, so even if I'm pretty sure that isn't the same
issue I'd like to know what is going to bite me sooner or later =)


Ouch, forgot to mention, the signal handlers do not work any longer if I 
create threads before starting the signal handlers.


Markus

Besides, why does the list reply to user per default?

___
libev mailing list
libev@lists.schmorp.de
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev