Kirill Timofeev | 15 Dec 01:11 2014
Picon

failures with "libev: ev_io_start called with corrupted watcher", ((WL)w)->next != (WL)w)

Hi folks,

I have application using libev, which runs for months without issues. 
But sometime it fails with following message in the log:

Dec 14 03:55:48 els-abacus-prod-01 statsd-router: 2014-12-14 03:55:47 
ERROR ds_health_check_timer_cb: before ev_io_init else branch
Dec 14 03:55:48 els-abacus-prod-01 statsd-router: 2014-12-14 03:55:47 
ERROR ds_health_check_timer_cb: before ev_io_init else branch
Dec 14 03:55:48 els-abacus-prod-01 statsd-router: 2014-12-14 03:55:47 
ERROR ds_health_check_timer_cb: before ev_io_start
Dec 14 03:55:48 els-abacus-prod-01 statsd-router: 2014-12-14 03:55:47 
ERROR ds_health_check_timer_cb: before ev_io_start
Dec 14 03:55:48 els-abacus-prod-01 statsd-router: 2014-12-14 03:55:47 
ERROR ds_health_check_timer_cb: before ev_io_init else branch
Dec 14 03:55:48 els-abacus-prod-01 statsd-router: statsd-router: 
ev.c:3552: ev_io_start: Assertion `("libev: ev_io_start called with 
corrupted watcher", ((WL)w)->next != (WL)w)' failed.

Here is function, where failure occurs:

void ds_health_check_timer_cb(struct ev_loop *loop, struct ev_periodic 
*p, int revents) {
     int i;
     int health_fd;
     struct ev_io *watcher;

     for (i = 0; i < global.downstream_num; i++) {
         watcher = (struct ev_io *)(&global.downstream[i].health_watcher);
         health_fd = watcher->fd;
(Continue reading)

Matthew Iversen | 11 Dec 06:21 2014

config.guess and config.sub out of date

Hi there.

I'd like to simply report that the config.guess and config.sub files are very out of date in the libev releases. e.g in 4.19 they are from 2008.

Recently this has caused a user a problem in a python library (gevent) using libev, here: https://github.com/gevent/gevent/issues/502

The most recent versions of these files are from this / last month. Available here:

http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD

If there's no reason not to it would be great if you could update these for the next release of libev. Many thanks,

Matt Iversen
-- Matt Iversen // matt <at> notevencode.com PGP: 0xc046e8a874522973 // 2F04 3DCC D6E6 D5AC D262 2E0B C046 E8A8 7452 2973
_______________________________________________
libev mailing list
libev <at> lists.schmorp.de
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
Alejandro Mery | 11 Dec 18:16 2014
Picon

[PATCH] configure.ac: fix syntax error in ./configure

dnl eats the new line between both statements

./configure: line 2815: syntax error near unexpected token `ac_config_headers="$ac_config_headers config.h"'
./configure: line 2815: `fi ac_config_headers="$ac_config_headers config.h"'

this is still a problem with autoconf 2.69 compiling libev-4.19 from sources

autoconf 2.69 on Ubuntu 14.04.1 LTS x86_64

thanks,
Alejandro Mery

---
 configure.ac | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configure.ac b/configure.ac
index 7e2d5e3..69e0c43 100644
--- a/configure.ac
+++ b/configure.ac
 <at>  <at>  -5,6 +5,7  <at>  <at>  orig_CFLAGS="$CFLAGS"
 AC_CONFIG_SRCDIR([ev_epoll.c])

 AM_INIT_AUTOMAKE(libev,4.19) dnl also update ev.h!
+
 AC_CONFIG_HEADERS([config.h])
 AM_MAINTAINER_MODE

--

-- 
2.2.0
Noam Camus | 2 Dec 12:33 2014

EV_CHILD_ENABLE/EV_SIGNAL_ENABLE

Hello

 

I saw in "Changes" file that under '4.00 Mon Oct 25 12:32:12 CEST 2010' there is:

-          new EV_CHILD_ENABLE and EV_SIGNAL_ENABLE configurable settings.

 

I wish to know how one should control these definitions?

 

This is since I see no support for that in configure.

Is there a way to use configure to pass extra cflags?

 

Thanks

Noam

_______________________________________________
libev mailing list
libev <at> lists.schmorp.de
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
Anthony Clark | 13 Nov 23:34 2014
Picon

Threaded Example clarification

Hey all,

First off. Thanks for libev - it's great. I've having issues understand the fundamentals of allowing loops to be modified via other threads. I've skimmed most of the mailing list and couldn't find a solution to this. I think my confusion comes from the documentation, where it states:

"""
Instead of invoking all pending watchers, the l_invoke callback will signal the main thread via some unspecified mechanism (signals? pipe writes? Async::Interrupt?)

"""
    1  static void
    2    l_invoke (EV_P)
    3    {
    4      userdata *u = ev_userdata (EV_A);
    5 
    6      while (ev_pending_count (EV_A))
    7        {
    8          wake_up_other_thread_in_some_magic_or_not_so_magic_way ();
    9          pthread_cond_wait (&u->invoke_cv, &u->lock);
   10        }
   11    }


I tried going through the perl module but I never saw what `sig_func` or `sig_arg` were. Maybe if I knew those, I'd get a hint. Since the loop (in the Thread Locking example) is processes solely in a separate (from main) thread, what could/would the main thread need to know about? Maybe cleaning up my other confusion below might answer this.

It doesn't appear that `real_invoke_pending` is never actually invoked in the Thread Locking example. In the perl module, it's handled by the module system (c_func) and I can't really figure it out where in the flow it's actually invoked.

    1    static void
    2    real_invoke_pending (EV_P)
    3    {
    4      userdata *u = ev_userdata (EV_A);
    5 
    6      pthread_mutex_lock (&u->lock);
    7      ev_invoke_pending (EV_A);
    8      pthread_cond_signal (&u->invoke_cv);
    9      pthread_mutex_unlock (&u->lock);
   10    }

So to narrow it down. I understand the acquire/release callbacks, I understand locking `ev_run`. I guess I just don't understand the flow of the invoke_pending callback. Any help is appreciated! Also, sorry for the newbie questions.

_______________________________________________
libev mailing list
libev <at> lists.schmorp.de
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
Anthony Clark | 13 Nov 23:33 2014
Picon

(unknown)

Hey all,

First off. Thanks for libev - it's great. I've having issues understand the fundamentals of allowing loops to be modified via other threads. I've skimmed most of the mailing list and couldn't find a solution to this. I think my confusion comes from the documentation, where it states:

"""
Instead of invoking all pending watchers, the l_invoke callback will signal the main thread via some unspecified mechanism (signals? pipe writes? Async::Interrupt?)

"""
    1  static void
    2    l_invoke (EV_P)
    3    {
    4      userdata *u = ev_userdata (EV_A);
    5 
    6      while (ev_pending_count (EV_A))
    7        {
    8          wake_up_other_thread_in_some_magic_or_not_so_magic_way ();
    9          pthread_cond_wait (&u->invoke_cv, &u->lock);
   10        }
   11    }


I tried going through the perl module but I never saw what `sig_func` or `sig_arg` were. Maybe if I knew those, I'd get a hint. Since the loop (in the Thread Locking example) is processes solely in a separate (from main) thread, what could/would the main thread need to know about? Maybe cleaning up my other confusion below might answer this.

It doesn't appear that `real_invoke_pending` is never actually invoked in the Thread Locking example. In the perl module, it's handled by the module system (c_func) and I can't really figure it out where in the flow it's actually invoked.

    1    static void
    2    real_invoke_pending (EV_P)
    3    {
    4      userdata *u = ev_userdata (EV_A);
    5 
    6      pthread_mutex_lock (&u->lock);
    7      ev_invoke_pending (EV_A);
    8      pthread_cond_signal (&u->invoke_cv);
    9      pthread_mutex_unlock (&u->lock);
   10    }

So to narrow it down. I understand the acquire/release callbacks, I understand locking `ev_run`. I guess I just don't understand the flow of the invoke_pending callback. Any help is appreciated! Also, sorry for the newbie questions.

-ac


_______________________________________________
libev mailing list
libev <at> lists.schmorp.de
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
Jamie Doran | 3 Nov 16:52 2014
Picon

Re: libev / multiple threads / multiple loops

Hi Shueng Chuan,

Thank you for your suggestion - it worked a treat.  The callbacks are now being invoked on the worker threads and I can utilize all cpu cores.

The simple fixes are always the best !

Jamie


On Mon, Nov 3, 2014 at 2:50 PM, KIU Shueng Chuan <nixchuan <at> gmail.com> wrote:

It seems from the manpage that you would need to make your constructor like the following:

Worker(int id) : m_id(id), m_timer(m_loop)
{ ... }

Otherwise, it defaults to using the default loop.


_______________________________________________
libev mailing list
libev <at> lists.schmorp.de
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
Jamie Doran | 3 Nov 13:39 2014
Picon

libev / multiple threads / multiple loops

Hi,

I am looking at using libev in a multi-threading process and am trying to understand how callbacks are invoked on individual threads.

My test program (see below) creates a number of worker threads, each with its own dynamic loop.  As a test, I create a periodic timer on each thread and when it expires do some work. 

Because each worker thread has its own loop instance and is polling that i.e. loop.run(0) then it should operate independent of the main thread where the default loop is ?   i.e. the invocation of the callback would be done on the "worker" thread. Instead I see that the callbacks for all workers are in fact executed on the main thread where the default loop is running.

Perhaps I am misunderstanding something fundamental about libev and my apologies if I am but I would be grateful if you could point this out to me and why it works this way. 

The attached example is only just that to illustrate the point but I would like something where a specific worker with its own thread could do some socket io independent of the main thread.

Does this make sense?

Thanks,
Jamie


#include <stdio.h>
#include <stdlib.h>
#include <ev.h>
#include <ev++.h>
#include<pthread.h>

pthread_barrier_t b;

void do_some_work(int id)
{
    printf("%s Id= %d thr_id= %lu\n\n", __FUNCTION__, id, pthread_self());
    long data = 230000;
    for (int i=0;i<2000;i++) {
        for (int j = 0; j < 1000; j++) {
            for (long z = 0; z < 300; z++) {
                data *= j;
                data <<8>>8;
            }
}
    }
}

class Worker {
    int                 m_id;
    ev::dynamic_loop    m_loop;
    ev::timer           m_timer;

    void timeout_cb(ev::timer &watcher, int revents) {
        printf("Worker: %s :  Id= %d <%lu>\n", __FUNCTION__, m_id, pthread_self());        
        do_some_work(m_id);
    }  
  
public:

    Worker(int id) : m_id(id) {
        m_timer.set<Worker,&Worker::timeout_cb>(this);
        m_timer.start(0., 1);
    }
    void run_event_loop() {
        printf("Worker: %s : id= %d thr_id= %lu\n", __FUNCTION__, m_id, pthread_self());
pthread_barrier_wait(&b);

            m_loop.run(0);
    }
};

void* start_worker(void* data)
{
    long id = (long)data;
    Worker *worker_module = 
        new Worker(id);
    worker_module->run_event_loop();
}
 
int main(int argc, char **argv) 
{
    ev::default_loop       loop;
    
    int err, numThreads = 1;
    if (argc>1)
        numThreads = strtol(&argv[1][0], NULL, 10);

    pthread_barrier_init(&b, 0, numThreads+1);

    pthread_t *thread_ids = (pthread_t *)malloc(numThreads*sizeof(pthread_t));
    for (int i=0;i<numThreads;i++) {
        pthread_create(&thread_ids[i], NULL, start_worker, (void *)i);
    }
    printf("%s thr_id = %lu\n", __FUNCTION__, pthread_self());    
    pthread_barrier_wait(&b);
    loop.run(0);

    for (int i=0;i<numThreads;i++) {
        pthread_join(thread_ids[i],NULL);
    }

    return 0;
}
_______________________________________________
libev mailing list
libev <at> lists.schmorp.de
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
Raphael 'kena' Poss | 8 Sep 21:58 2014
Picon
Picon

Bug in C++ wrapper

Dear all,

ev.h since modified in 4.15 is currently invalid when used from C++: it includes exception information
(throw()) for the typedef ev_loop_callback_nothrow, which is not legal in C++.

throw() is not part of a function's type, so it cannot be captured by typedef.

The correct fix is to remove EV_THROW on that particular typedef.

Best regards,

--

-- 
Raphael 'kena' Poss ยท r.poss <at> uva.nl
http://science.raphael.poss.name/

_______________________________________________
libev mailing list
libev <at> lists.schmorp.de
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
Ani A | 8 Sep 09:11 2014
Picon

Regarding: undefined symbol: ev_default_loop_ptr

Hello,

while I was trying to use libev, with lua-ev library, I got this
undefined symbol error,
I tried to search for solutions but I found only one discussion on a
Node.js forum related to the optimization (-O0 vs -O2)
I am not sure what is the correct option I should be using.

I tried to build libev.so from source as well (libev-4.18.tar.gz and
CFLAGS="-O0" )
still saw the same error

Can anyone please suggest what options (compile/linker) that I need to use.

I am on Ubuntu 12.04 LTS
gcc version 4.6.3

Thanks.
--
Ani
Marc Lehmann | 5 Sep 18:50 2014
Picon

libev-4.18 has just been released

I am pleased to announce libev 4.18!

Distribution: http://dist.schmorp.de/libev/libev-4.18.tar.gz
Documentation: http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod?pathrev=rel-4_18
Changes: http://cvs.schmorp.de/libev/Changes?pathrev=rel-4_18

This release is mainly a bugfix release. Unless you are directly affected
by one of the fixes, there is no urgent need to upgrade.

The complete Changes are:

4.18 Fri Sep  5 17:55:26 CEST 2014
        - events on files were not always generated properly with the
          epoll backend (testcase by Assaf Inbal).
        - mark event pipe fd as cloexec after a fork (analyzed by Sami Farin).
        - (ecb) support m68k, m88k and sh (patch by Miod Vallat).
        - use a reasonable fallback for EV_NSIG instead of erroring out
          when we can't detect the signal set size.
        - in the absence of autoconf, do not use the clock syscall
          on glibc >= 2.17 (avoids the syscall AND -lrt on systems
          doing clock_gettime in userspace).
        - ensure extern "C" function pointers are used for externally-visible
          loop callbacks (not watcher callbacks yet).
        - (ecb) work around memory barriers and volatile apparently both being
          broken in visual studio 2008 and later (analysed and patch by Nicolas Noble).

--

-- 
                The choice of a       Deliantra, the free code+content MORPG
      -----==-     _GNU_              http://www.deliantra.net
      ----==-- _       generation
      ---==---(_)__  __ ____  __      Marc Lehmann
      --==---/ / _ \/ // /\ \/ /      schmorp <at> schmorp.de
      -=====/_/_//_/\_,_/ /_/\_\

Gmane