// This file written in great part by Tim Johnson (Tim@TimMUD)
static void close_callback(int fd){
string mudname;
trr("close_callback: fd="+fd+"\n");
foreach(mudname in keys(muds_on_this_fd(fd))){
trr("Removing mud from connected_muds list: "+mudname);
mudinfo[mudname]["disconnect_time"] = time();
map_delete(connected_muds, mudname);
broadcast_mudlist(mudname);
}
close_connection(fd);
}
static void listen_callback(int fd){
int fdstat;
if ((fdstat = socket_accept(fd, "read_callback", "write_callback")) < 0) {
return;
}
}
void write_callback(int fd){
if (sockets[fd]["write_status"] == EEALREADY) {
write_data(fd, sockets[fd]["pending"]);
map_delete(sockets[fd], "pending");
}
else {
sockets[fd]["write_status"] = EESUCCESS;
}
}
static void write_data_retry(int fd, mixed data, int counter){
int rc;
if (counter == MAXIMUM_RETRIES) {
close_connection(fd);
return;
}
rc = socket_write(fd, data);
if(!sockets[fd]) sockets[fd]=([]); // Tim
sockets[fd]["write_status"] = rc;
switch (rc) {
case EESUCCESS:
break;
case EEALREADY:
sockets[fd]["pending"] = data;
break;
case EECALLBACK:
break;
case EESEND:
if (counter < MAXIMUM_RETRIES) {
trr("retry hit");
call_out("retry_write", 2, ({fd, data, counter + 1}));
return;
}
default:
trr("write_data_retry: " + socket_error(rc));
close_connection(fd);
break;
}
}
static void close_connection(int fd){
int sockerr;
map_delete(sockets, fd);
sockerr = socket_close(fd);
trr("closing sockerr:"+sockerr);
}
static void write_data(int fd, mixed data){
write_data_retry(fd, data, 0);
}
static void broadcast_data(mapping targets, mixed data){
foreach(int *arr in unique_array(values(targets), (: $1 :))){
write_data(arr[0], data);
}
}