egghelp.org community Forum Index
[ egghelp.org home | forum home ]
egghelp.org community
Discussion of eggdrop bots, shell accounts and tcl scripts.
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

vwait / binds / eventloop

 
Post new topic   Reply to topic    egghelp.org community Forum Index -> Modules & Programming
View previous topic :: View next topic  
Author Message
sKy
Op


Joined: 14 Apr 2005
Posts: 194
Location: Germany

PostPosted: Wed Mar 15, 2006 9:04 am    Post subject: vwait / binds / eventloop Reply with quote

Using vwait in combination with an eggdrop has a big disadventage:
As long you vwait the bot won`t process any binds. Neither internal binds (such as the ping pong event) nor user-defined binds. In final result the bot won`t respond to any binds you have set and if you vwait to long the bot will ping out on irc.

With this reason it would be really amazing if:
- Eggdrop binds
- (u)timer
- maybe something else?
would be dealt as 'regular' tclevents in the tcleventqueue.

Perhaps someone already made this kind of change in eggdrop`s code or want to make such a fix?
_________________
socketapi | Code less, create more.
Back to top
View user's profile Send private message
De Kus
Revered One


Joined: 15 Dec 2002
Posts: 1361
Location: Germany

PostPosted: Wed Mar 15, 2006 9:32 am    Post subject: Reply with quote

where is the problem about not using vwait? I can't think of any reason you would need vwait to use in eggdrops.
_________________
De Kus
StarZ|De_Kus, De_Kus or DeKus on IRC
Copyright © 2005-2009 by De Kus - published under The MIT License
Love hurts, love strengthens...
Back to top
View user's profile Send private message MSN Messenger
sKy
Op


Joined: 14 Apr 2005
Posts: 194
Location: Germany

PostPosted: Wed Mar 15, 2006 12:52 pm    Post subject: Reply with quote

I think vwait is quite usefull in a lot of situations.
- fcopy
- Working with sockets, especial socket -server.
- working with http
- working with packages
- bind join, waiting for infos from whois directly in the joinproc after the whois is done or timeout
For some situaitons you may use workarrounds but the vwait command would be so much more usefull.

Do you think it would be complete useless?
_________________
socketapi | Code less, create more.
Back to top
View user's profile Send private message
De Kus
Revered One


Joined: 15 Dec 2002
Posts: 1361
Location: Germany

PostPosted: Wed Mar 15, 2006 1:45 pm    Post subject: Reply with quote

well you can almost everytime get the async behavior by using fileevent.
http has fileevents with callbacks already included, sockets work find with them server anyway. and where is the problem to bind for whois numeric for join binds? they are all much less trouble then somehow getting vwait to work. You kind of get vwait at any end of an script, because eggdrop loops until an event occours which basicly is what vwaits does afaik... it cyles in idle mode until an event occurs.
_________________
De Kus
StarZ|De_Kus, De_Kus or DeKus on IRC
Copyright © 2005-2009 by De Kus - published under The MIT License
Love hurts, love strengthens...
Back to top
View user's profile Send private message MSN Messenger
sKy
Op


Joined: 14 Apr 2005
Posts: 194
Location: Germany

PostPosted: Wed Mar 15, 2006 2:22 pm    Post subject: Reply with quote

I try to make an example. What i mean is some kind of:

Code:

# this would be so usefull (but only possible if vwait would work)

bind join - * joinproc

proc joinproc { nickname hostname handle channel } {

   # getting some extra private vars
   # set extrainfo [subproc $handle $channel]

   # wait until the whois is done.....

   after $timeoutsetting.... [list set ::user_info(whois_end,$nickname) 0]
   vwait ::user_info(whois_end,$nickname)
   if { $::user_info(whois_end,$nickname) == 0 } {
      # whois not done......
      # processing if no whois done.........
      return
   }

   # the whois is done and we can use all variables we got from whois
   # and all previous private variables we got
   # processing .....

}

#
#
#

# raw realname
bind raw - 311 raw:311

proc raw:311 { from key text } {
   set nickname [lindex [split $text " "] 1]
   set realname [lindex [split $text ":"] end]
   set ::user_info(real_name,$nickname) $realname
}



# raw authname
bind raw - 330 raw:330

proc raw:330 { from key text } {
   set nickname [lindex [split $text " "] 1]
   set authname [lindex [split $text " "] 2]
   set ::user_info(authname,$nickname) $authname
}


# raw end of whois
bind raw - 318 raw:318

proc raw:318 { from key text } {
   set nick_list [lindex [split $text " "] 1]
   set nick_list [split $nick_list ","]
   foreach nickname $nick_list {
      set ::user_info(whois_end,$nickname) 1
      whois_done_callback $nickname
   }
}

# just example, need many other binds about whois like channels, away and so on

# need bind if whois failed (no such nickname raw reply)

#
#
#


# the current usual/impractically way

proc whois_done_callback { nickname } {
   # uhm, well
   # don`t know which channel he joined - would need to store this in a global variable aswell too

   # but what if he is already parted/offline?

   # what if he joined two or more of the bots channels in a short amount of time

   # need the hostname of the user --> getchanhost? --> no if he is not longer in chan then this will be return ""
   # so we need to store this info aswell too
}


Sure we can handle all this with a callback proc.... But this will amand more code each time. With a working vwait command this would look more easy. Just wanted to show you my point. =)
_________________
socketapi | Code less, create more.
Back to top
View user's profile Send private message
De Kus
Revered One


Joined: 15 Dec 2002
Posts: 1361
Location: Germany

PostPosted: Thu Mar 16, 2006 6:01 am    Post subject: Reply with quote

you would simply have to add more data into the global var and process it in the last raw bind. The increasing memory usuage should be irrelevant and the amount of code should be about the same, since you simply need to move then code and change the var names.
You would have add something to check which whois reply belongs to which whois request anyway. I would suggest using a table and always get and remove entry 0, since the replies should come in same order than the requests. (to have even more reliability you could check if lsearch returns 0 looking for the send nick and if not change it to 0 for all expected replies. if you save a timestamp you can addionally rerequest any request which was made while bot was online but got no reply for 5min)
Don't forget you might send out more whois replies than you have already recived and therefore while sending request 4 and wait you might get reply 2. Remember you wanted to have other bind joins trigger while vwait and therefore other requests will be send and more replies will be awaited. Correct me, if I am wrong.
_________________
De Kus
StarZ|De_Kus, De_Kus or DeKus on IRC
Copyright © 2005-2009 by De Kus - published under The MIT License
Love hurts, love strengthens...
Back to top
View user's profile Send private message MSN Messenger
thommey
Halfop


Joined: 01 Apr 2008
Posts: 73

PostPosted: Tue Mar 03, 2009 10:21 am    Post subject: TCL8.6 Reply with quote

I'm digging that old topic out again because Tcl8.6 actually provides a more convenient solution to the initial problem - coroutines:

Code:

bind join - * query_userinfo
proc query_userinfo {nick host hand chan text} {
# already waiting for information for that nick? (maybe for another channel, won't solve that for this snippet)
  if {[info commands queryinfo_$nick] != ""} { return }
  coroutine queryinfo_$nick queryinfo_template $nick $chan
}

proc queryinfo_template {nick chan} {
  putserv "WHOIS $nick"
# pause the execution
  yield
  putserv "PRIVMSG $chan :Hi $nick, your realname is: '$::userinfo_realname($nick)'."
  if {[info exists ::userinfo_identification($nick)]} {
    putserv "PRIVMSG $chan :$nick, you're identified as '$::userinfo_identification($nick)'"
    unset ::userinfo_identification($nick)
  }
  unset ::userinfo_realname($nick)
}

# raw realname
bind raw - 311 raw:311
proc raw:311 { from key text } {
set realname [join [lassign [split $text] trash nick]]
if {[string index $realname 0] == ":"} {
  set realname [string range $realname 1 end]
}
set ::userinfo_realname($nick) $realname
}


# raw authname
bind raw - 330 raw:330
proc raw:330 { from key text } {
lassign [split $text] trash nick login
set ::userinfo_identification($nick) $login
}


# raw end of whois
bind raw - 318 raw:318
proc raw:318 { from key text } {
  set nick_list [lindex [split $text] 1]
  set nick_list [split $nick_list ","]
  foreach nickname $nick_list {
    if {[info commands queryinfo_$nick] != ""} {
# continue execution
      queryinfo_$nick
    }
  }
}


Check http://wiki.tcl.tk/21446 for further information on the coroutine-feature.
Back to top
View user's profile Send private message
thommey
Halfop


Joined: 01 Apr 2008
Posts: 73

PostPosted: Fri Mar 20, 2009 7:18 am    Post subject: Reply with quote

And here's a patch against eggdrop1.6.19 to get vwait to parse eggdrop events:
Code:

diff -urN eggdrop1.6.19/src/main.c eggdrop1.6.19+vwait/src/main.c
--- eggdrop1.6.19/src/main.c   2008-02-16 22:41:03.000000000 +0100
+++ eggdrop1.6.19+vwait/src/main.c   2009-03-05 19:41:19.000000000 +0100
@@ -129,6 +129,9 @@
 int resolve_timeout = 15; /* Hostname/address lookup timeout        */
 char quit_msg[1024];      /* Quit message                           */
 
+int orig_argc = 0;
+char **orig_argv = NULL;
+
 /* Traffic stats */
 unsigned long otraffic_irc = 0;
 unsigned long otraffic_irc_today = 0;
@@ -705,10 +708,186 @@
     run_cnt++;
 }
 
+void eventloop() {
+  int xx, i;
+  char buf[520];
+  int socket_cleanup = 0;
+
+#ifdef USE_TCL_EVENTS
+    /* Process a single tcl event */
+  Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT);
+#endif /* USE_TCL_EVENTS */
+
+  /* Lets move some of this here, reducing the numer of actual
+   * calls to periodic_timers
+   */
+  now = time(NULL);
+  random();                   /* Woop, lets really jumble things */
+  if (now != then) {          /* Once a second */
+    call_hook(HOOK_SECONDLY);
+    then = now;
+  }
+
+  /* Only do this every so often. */
+  if (!socket_cleanup) {
+    socket_cleanup = 5;
+
+    /* Remove dead dcc entries. */
+    dcc_remove_lost();
+
+    /* Check for server or dcc activity. */
+    dequeue_sockets();
+  } else
+    socket_cleanup--;
+
+  /* Free unused structures. */
+  garbage_collect();
+
+  xx = sockgets(buf, &i);
+  if (xx >= 0) {              /* Non-error */
+    int idx;
+
+    for (idx = 0; idx < dcc_total; idx++)
+      if (dcc[idx].sock == xx) {
+        if (dcc[idx].type && dcc[idx].type->activity) {
+          /* Traffic stats */
+          if (dcc[idx].type->name) {
+            if (!strncmp(dcc[idx].type->name, "BOT", 3))
+              itraffic_bn_today += strlen(buf) + 1;
+            else if (!strcmp(dcc[idx].type->name, "SERVER"))
+              itraffic_irc_today += strlen(buf) + 1;
+            else if (!strncmp(dcc[idx].type->name, "CHAT", 4))
+              itraffic_dcc_today += strlen(buf) + 1;
+            else if (!strncmp(dcc[idx].type->name, "FILES", 5))
+              itraffic_dcc_today += strlen(buf) + 1;
+            else if (!strcmp(dcc[idx].type->name, "SEND"))
+              itraffic_trans_today += strlen(buf) + 1;
+            else if (!strncmp(dcc[idx].type->name, "GET", 3))
+              itraffic_trans_today += strlen(buf) + 1;
+            else
+              itraffic_unknown_today += strlen(buf) + 1;
+          }
+          dcc[idx].type->activity(idx, buf, i);
+        } else
+          putlog(LOG_MISC, "*",
+                 "!!! untrapped dcc activity: type %s, sock %d",
+                 dcc[idx].type->name, dcc[idx].sock);
+        break;
+      }
+  } else if (xx == -1) {        /* EOF from someone */
+    int idx;
+
+    if (i == STDOUT && !backgrd)
+      fatal("END OF FILE ON TERMINAL", 0);
+    for (idx = 0; idx < dcc_total; idx++)
+      if (dcc[idx].sock == i) {
+        if (dcc[idx].type && dcc[idx].type->eof)
+          dcc[idx].type->eof(idx);
+        else {
+          putlog(LOG_MISC, "*",
+                 "*** ATTENTION: DEAD SOCKET (%d) OF TYPE %s UNTRAPPED",
+                 i, dcc[idx].type ? dcc[idx].type->name : "*UNKNOWN*");
+          killsock(i);
+          lostdcc(idx);
+        }
+        idx = dcc_total + 1;
+      }
+    if (idx == dcc_total) {
+      putlog(LOG_MISC, "*",
+             "(@) EOF socket %d, not a dcc socket, not anything.", i);
+      close(i);
+      killsock(i);
+    }
+  } else if (xx == -2 && errno != EINTR) {      /* select() error */
+    putlog(LOG_MISC, "*", "* Socket error #%d; recovering.", errno);
+    for (i = 0; i < dcc_total; i++) {
+      if ((fcntl(dcc[i].sock, F_GETFD, 0) == -1) && (errno == EBADF)) {
+        putlog(LOG_MISC, "*",
+               "DCC socket %d (type %d, name '%s') expired -- pfft",
+               dcc[i].sock, dcc[i].type, dcc[i].nick);
+        killsock(dcc[i].sock);
+        lostdcc(i);
+        i--;
+      }
+    }
+  } else if (xx == -3) {
+    call_hook(HOOK_IDLE);
+    socket_cleanup = 0;       /* If we've been idle, cleanup & flush */
+  }
+
+  if (do_restart) {
+    if (do_restart == -2)
+      rehash();
+    else {
+      /* Unload as many modules as possible */
+      int f = 1;
+      module_entry *p;
+      Function startfunc;
+      char name[256];
+
+      /* oops, I guess we should call this event before tcl is restarted */
+      check_tcl_event("prerestart");
+
+      while (f) {
+        f = 0;
+        for (p = module_list; p != NULL; p = p->next) {
+          dependancy *d = dependancy_list;
+          int ok = 1;
+
+          while (ok && d) {
+            if (d->needed == p)
+              ok = 0;
+            d = d->next;
+          }
+          if (ok) {
+            strcpy(name, p->name);
+            if (module_unload(name, botnetnick) == NULL) {
+              f = 1;
+              break;
+            }
+          }
+        }
+      }
+
+      /* Make sure we don't have any modules left hanging around other than
+       * "eggdrop" and the two that are supposed to be.
+       */
+      for (f = 0, p = module_list; p; p = p->next) {
+        if (strcmp(p->name, "eggdrop") && strcmp(p->name, "encryption") &&
+            strcmp(p->name, "uptime")) {
+          f++;
+        }
+      }
+      if (f != 0) {
+        putlog(LOG_MISC, "*", MOD_STAGNANT);
+      }
+
+      flushlogs();
+      kill_tcl();
+      init_tcl(orig_argc, orig_argv);
+      init_language(0);
+
+      /* this resets our modules which we didn't unload (encryption and uptime) */
+      for (p = module_list; p; p = p->next) {
+        if (p->funcs) {
+          startfunc = p->funcs[MODCALL_START];
+          startfunc(NULL);
+        }
+      }
+
+      rehash();
+      restart_chons();
+      call_hook(HOOK_LOADED);
+    }
+
+    do_restart = 0;
+  }
+}
+
 int main(int argc, char **argv)
 {
   int xx, i;
-  char buf[520], s[25];
+  char s[25];
   FILE *f;
   struct sigaction sv;
   struct chanset_t *chan;
@@ -930,178 +1109,11 @@
 
   call_hook(HOOK_LOADED);
 
+  orig_argc = argc;
+  orig_argv = argv;
+
   debug0("main: entering loop");
   while (1) {
-    int socket_cleanup = 0;
-
-#ifdef USE_TCL_EVENTS
-    /* Process a single tcl event */
-    Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT);
-#endif /* USE_TCL_EVENTS */
-
-    /* Lets move some of this here, reducing the numer of actual
-     * calls to periodic_timers
-     */
-    now = time(NULL);
-    random();                   /* Woop, lets really jumble things */
-    if (now != then) {          /* Once a second */
-      call_hook(HOOK_SECONDLY);
-      then = now;
-    }
-
-    /* Only do this every so often. */
-    if (!socket_cleanup) {
-      socket_cleanup = 5;
-
-      /* Remove dead dcc entries. */
-      dcc_remove_lost();
-
-      /* Check for server or dcc activity. */
-      dequeue_sockets();
-    } else
-      socket_cleanup--;
-
-    /* Free unused structures. */
-    garbage_collect();
-
-    xx = sockgets(buf, &i);
-    if (xx >= 0) {              /* Non-error */
-      int idx;
-
-      for (idx = 0; idx < dcc_total; idx++)
-        if (dcc[idx].sock == xx) {
-          if (dcc[idx].type && dcc[idx].type->activity) {
-            /* Traffic stats */
-            if (dcc[idx].type->name) {
-              if (!strncmp(dcc[idx].type->name, "BOT", 3))
-                itraffic_bn_today += strlen(buf) + 1;
-              else if (!strcmp(dcc[idx].type->name, "SERVER"))
-                itraffic_irc_today += strlen(buf) + 1;
-              else if (!strncmp(dcc[idx].type->name, "CHAT", 4))
-                itraffic_dcc_today += strlen(buf) + 1;
-              else if (!strncmp(dcc[idx].type->name, "FILES", 5))
-                itraffic_dcc_today += strlen(buf) + 1;
-              else if (!strcmp(dcc[idx].type->name, "SEND"))
-                itraffic_trans_today += strlen(buf) + 1;
-              else if (!strncmp(dcc[idx].type->name, "GET", 3))
-                itraffic_trans_today += strlen(buf) + 1;
-              else
-                itraffic_unknown_today += strlen(buf) + 1;
-            }
-            dcc[idx].type->activity(idx, buf, i);
-          } else
-            putlog(LOG_MISC, "*",
-                   "!!! untrapped dcc activity: type %s, sock %d",
-                   dcc[idx].type->name, dcc[idx].sock);
-          break;
-        }
-    } else if (xx == -1) {        /* EOF from someone */
-      int idx;
-
-      if (i == STDOUT && !backgrd)
-        fatal("END OF FILE ON TERMINAL", 0);
-      for (idx = 0; idx < dcc_total; idx++)
-        if (dcc[idx].sock == i) {
-          if (dcc[idx].type && dcc[idx].type->eof)
-            dcc[idx].type->eof(idx);
-          else {
-            putlog(LOG_MISC, "*",
-                   "*** ATTENTION: DEAD SOCKET (%d) OF TYPE %s UNTRAPPED",
-                   i, dcc[idx].type ? dcc[idx].type->name : "*UNKNOWN*");
-            killsock(i);
-            lostdcc(idx);
-          }
-          idx = dcc_total + 1;
-        }
-      if (idx == dcc_total) {
-        putlog(LOG_MISC, "*",
-               "(@) EOF socket %d, not a dcc socket, not anything.", i);
-        close(i);
-        killsock(i);
-      }
-    } else if (xx == -2 && errno != EINTR) {      /* select() error */
-      putlog(LOG_MISC, "*", "* Socket error #%d; recovering.", errno);
-      for (i = 0; i < dcc_total; i++) {
-        if ((fcntl(dcc[i].sock, F_GETFD, 0) == -1) && (errno == EBADF)) {
-          putlog(LOG_MISC, "*",
-                 "DCC socket %d (type %d, name '%s') expired -- pfft",
-                 dcc[i].sock, dcc[i].type, dcc[i].nick);
-          killsock(dcc[i].sock);
-          lostdcc(i);
-          i--;
-        }
-      }
-    } else if (xx == -3) {
-      call_hook(HOOK_IDLE);
-      socket_cleanup = 0;       /* If we've been idle, cleanup & flush */
-    }
-
-    if (do_restart) {
-      if (do_restart == -2)
-        rehash();
-      else {
-        /* Unload as many modules as possible */
-        int f = 1;
-        module_entry *p;
-        Function startfunc;
-        char name[256];
-
-        /* oops, I guess we should call this event before tcl is restarted */
-        check_tcl_event("prerestart");
-
-        while (f) {
-          f = 0;
-          for (p = module_list; p != NULL; p = p->next) {
-            dependancy *d = dependancy_list;
-            int ok = 1;
-
-            while (ok && d) {
-              if (d->needed == p)
-                ok = 0;
-              d = d->next;
-            }
-            if (ok) {
-              strcpy(name, p->name);
-              if (module_unload(name, botnetnick) == NULL) {
-                f = 1;
-                break;
-              }
-            }
-          }
-        }
-
-        /* Make sure we don't have any modules left hanging around other than
-         * "eggdrop" and the two that are supposed to be.
-         */
-        for (f = 0, p = module_list; p; p = p->next) {
-          if (strcmp(p->name, "eggdrop") && strcmp(p->name, "encryption") &&
-              strcmp(p->name, "uptime")) {
-            f++;
-          }
-        }
-        if (f != 0) {
-          putlog(LOG_MISC, "*", MOD_STAGNANT);
-        }
-
-        flushlogs();
-        kill_tcl();
-        init_tcl(argc, argv);
-        init_language(0);
-
-        /* this resets our modules which we didn't unload (encryption and uptime) */
-        for (p = module_list; p; p = p->next) {
-          if (p->funcs) {
-            startfunc = p->funcs[MODCALL_START];
-            startfunc(NULL);
-          }
-        }
-
-        rehash();
-        restart_chons();
-        call_hook(HOOK_LOADED);
-      }
-
-      do_restart = 0;
-    }
+    eventloop();
   }
 }
diff -urN eggdrop1.6.19/src/patch.h eggdrop1.6.19+vwait/src/patch.h
--- eggdrop1.6.19/src/patch.h   2008-04-19 06:21:20.000000000 +0200
+++ eggdrop1.6.19+vwait/src/patch.h   2009-03-05 19:42:43.000000000 +0100
@@ -36,7 +36,7 @@
  *
  *
  */
-/* PATCH GOES HERE */
+patch("vwait");
 /*
  *
  *
diff -urN eggdrop1.6.19/src/proto.h eggdrop1.6.19+vwait/src/proto.h
--- eggdrop1.6.19/src/proto.h   2008-02-16 22:41:04.000000000 +0100
+++ eggdrop1.6.19+vwait/src/proto.h   2009-03-05 19:41:16.000000000 +0100
@@ -181,6 +181,7 @@
 void eggContextNote(const char *, int, const char *, const char *);
 void eggAssert(const char *, int, const char *);
 void backup_userfile(void);
+void eventloop(void);
 
 /* match.c */
 int _wild_match(register unsigned char *, register unsigned char *);
diff -urN eggdrop1.6.19/src/tclmisc.c eggdrop1.6.19+vwait/src/tclmisc.c
--- eggdrop1.6.19/src/tclmisc.c   2008-02-16 22:41:04.000000000 +0100
+++ eggdrop1.6.19+vwait/src/tclmisc.c   2009-03-05 19:41:23.000000000 +0100
@@ -55,6 +55,7 @@
 extern int max_logs;
 extern log_t *logs;
 extern Tcl_Interp *interp;
+void mainbody();
 
 int expmem_tclmisc()
 {
@@ -705,6 +706,49 @@
   return TCL_OK;
 }
 
+static char *tcl_vwait_var STDVAR
+{
+    int *donePtr = (int *) cd;
+    *donePtr = 1;
+    return NULL;
+}
+
+static int tcl_vwait STDVAR
+{
+  int done;
+
+  BADARGS(2, 2, " name");
+
+  if (Tcl_TraceVar(interp, argv[1],
+          TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+          tcl_vwait_var, (ClientData) &done) != TCL_OK) {
+      return TCL_ERROR;
+  };
+  done = 0;
+  while (!done) {
+      eventloop();
+      if (Tcl_LimitExceeded(interp)) {
+          break;
+      }
+  }
+  Tcl_UntraceVar(interp, argv[1],
+          TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+          tcl_vwait_var, (ClientData) &done);
+
+  /*
+   * Clear out the interpreter's result, since it may have been set by event
+   * handlers.
+   */
+
+  Tcl_ResetResult(interp);
+  if (!done) {
+      Tcl_AppendResult(interp, "limit exceeded", NULL);
+      return TCL_ERROR;
+  }
+  return TCL_OK;
+}
+
+
 tcl_cmds tclmisc_objcmds[] = {
 #ifdef USE_TCL_OBJ
   {"md5", tcl_md5},
@@ -750,5 +794,6 @@
   {"binds",               tcl_binds},
   {"callevent",       tcl_callevent},
   {"stripcodes",     tcl_stripcodes},
+  {"eggvwait",            tcl_vwait},
   {NULL,                       NULL}
 };


Last edited by thommey on Mon Mar 30, 2009 1:28 pm; edited 1 time in total
Back to top
View user's profile Send private message
scotteh
Halfop


Joined: 29 Jan 2006
Posts: 50

PostPosted: Fri Mar 20, 2009 12:48 pm    Post subject: Reply with quote

De Kus wrote:
well you can almost everytime get the async behavior by using fileevent.
http has fileevents with callbacks already included, sockets work find with them server anyway. and where is the problem to bind for whois numeric for join binds? they are all much less trouble then somehow getting vwait to work. You kind of get vwait at any end of an script, because eggdrop loops until an event occours which basicly is what vwaits does afaik... it cyles in idle mode until an event occurs.


Sadly async fileevents on rather idle eggdrops will only get called once each second. So http async calls can be a lot slower than their sync counterparts.
Back to top
View user's profile Send private message
thommey
Halfop


Joined: 01 Apr 2008
Posts: 73

PostPosted: Mon Mar 30, 2009 1:30 pm    Post subject: Reply with quote

scotteh wrote:

Sadly async fileevents on rather idle eggdrops will only get called once each second. So http async calls can be a lot slower than their sync counterparts.


You're right. I changed my patch to create a new command called "eggvwait" instead of overwriting tcls vwait, so it can at least be safely patched without breaking the http module and other things which rely on the fast eventchecking. To *really* solve that issue we'd need to overwrite Tcls notifier (ugh).
Back to top
View user's profile Send private message
MrStonedOne
Voice


Joined: 25 Feb 2007
Posts: 8

PostPosted: Sun Nov 15, 2009 12:25 pm    Post subject: Reply with quote

scotteh wrote:

Sadly async fileevents on rather idle eggdrops will only get called once each second. So http async calls can be a lot slower than their sync counterparts.


well a dirty way to fix that is to do
Code:
utimer 0 vwaitfix;proc vwaitfix {} {update;utimer 0 vwaitfix}


if done right it should have async http calls going 500+ times a sec. and doing so will also make it so 'after idle/ms {script}' works.
Back to top
View user's profile Send private message
thommey
Halfop


Joined: 01 Apr 2008
Posts: 73

PostPosted: Thu Nov 19, 2009 9:00 pm    Post subject: Reply with quote

Wow, that's really dirty.
Better apply:
Code:

diff -pNurX excludes eggdrop1.6.original/src/main.c eggdrop1.6.modified.tcleventloop/src/main.c
--- eggdrop1.6.original/src/main.c      2009-10-12 16:10:32.000000000 +0200
+++ eggdrop1.6.modified.tcleventloop/src/main.c 2009-11-20 02:00:00.000000000 +0100
@@ -941,7 +941,7 @@ int main(int argc, char **argv)
 
 #ifdef USE_TCL_EVENTS
     /* Process a single tcl event */
-    Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT);
+    while (Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT)) ;
 #endif /* USE_TCL_EVENTS */
 
     /* Lets move some of this here, reducing the numer of actual

Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    egghelp.org community Forum Index -> Modules & Programming All times are GMT - 4 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Forum hosting provided by Reverse.net

Powered by phpBB © 2001, 2005 phpBB Group
subGreen style by ktauber