This is the new home of the egghelp.org community forum.
All data has been migrated (including user logins/passwords) to a new phpBB version.


For more information, see this announcement post. Click the X in the top right-corner of this box to dismiss this message.

vwait / binds / eventloop

Discussion of Eggdrop's code and module programming in C.
Post Reply
User avatar
sKy
Op
Posts: 194
Joined: Thu Apr 14, 2005 5:58 pm
Location: Germany

vwait / binds / eventloop

Post by sKy »

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.
User avatar
De Kus
Revered One
Posts: 1361
Joined: Sun Dec 15, 2002 11:41 am
Location: Germany

Post by De Kus »

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...
User avatar
sKy
Op
Posts: 194
Joined: Thu Apr 14, 2005 5:58 pm
Location: Germany

Post by sKy »

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.
User avatar
De Kus
Revered One
Posts: 1361
Joined: Sun Dec 15, 2002 11:41 am
Location: Germany

Post by De Kus »

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...
User avatar
sKy
Op
Posts: 194
Joined: Thu Apr 14, 2005 5:58 pm
Location: Germany

Post by sKy »

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

Code: Select all

# 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.
User avatar
De Kus
Revered One
Posts: 1361
Joined: Sun Dec 15, 2002 11:41 am
Location: Germany

Post by De Kus »

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...
t
thommey
Halfop
Posts: 76
Joined: Tue Apr 01, 2008 2:59 pm

TCL8.6

Post by thommey »

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

Code: Select all

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.
t
thommey
Halfop
Posts: 76
Joined: Tue Apr 01, 2008 2:59 pm

Post by thommey »

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

Code: Select all

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.
s
scotteh
Halfop
Posts: 50
Joined: Sun Jan 29, 2006 12:43 am

Post by scotteh »

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.
t
thommey
Halfop
Posts: 76
Joined: Tue Apr 01, 2008 2:59 pm

Post by thommey »

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).
M
MrStonedOne
Voice
Posts: 8
Joined: Sun Feb 25, 2007 8:36 am

Post by MrStonedOne »

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: Select all

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.
t
thommey
Halfop
Posts: 76
Joined: Tue Apr 01, 2008 2:59 pm

Post by thommey »

Wow, that's really dirty.
Better apply:

Code: Select all

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

Post Reply