fix invalid select() usage
parent
3cbd72c82a
commit
cfdaa293c9
|
@ -1,3 +1,23 @@
|
|||
0.62:
|
||||
|
||||
- vocabulary section: what is the dictionary?
|
||||
- document swons, uncons, unswons
|
||||
- vector-push/pop examples
|
||||
- vector-each/map examples
|
||||
- string construction examples
|
||||
- string construction ackward
|
||||
- sbuf-hashcode
|
||||
- vector-hashcode
|
||||
- test substitute, set-nth, remove-nth
|
||||
- listener backspace overzealous
|
||||
- SIGBUS handler
|
||||
- handle division by zero
|
||||
- errors: don't show .factor-rc
|
||||
- inspector: sort
|
||||
- accept: return socket, instead of printing msg
|
||||
- telnetd: needs own history
|
||||
- multitasking
|
||||
|
||||
[error] AWT-EventQueue-0: java.lang.NullPointerException
|
||||
[error] AWT-EventQueue-0: at sidekick.SideKickParsedData.getTreePathForPosition(Unknown Source)
|
||||
[error] AWT-EventQueue-0: at sidekick.SideKickParsedData.getTreePathForPosition(Unknown Source)
|
||||
|
@ -14,51 +34,32 @@
|
|||
[error] AWT-EventQueue-0: at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:137)
|
||||
[error] AWT-EventQueue-0: at java.awt.EventDispatchThread.run(EventDispatchThread.java:100)
|
||||
|
||||
+ docs:
|
||||
|
||||
- vocabulary section: what is the dictionary?
|
||||
- document swons, uncons, unswons
|
||||
- vector-push/pop examples
|
||||
- vector-each/map examples
|
||||
- string construction examples
|
||||
- string construction ackward
|
||||
|
||||
+ tests:
|
||||
|
||||
- java factor: equal numbers have non-equal hashcodes!
|
||||
- sbuf-hashcode
|
||||
- vector-hashcode
|
||||
- clone-sbuf
|
||||
- FactorLib.equal() not very good
|
||||
- test substitute, set-nth, remove-nth
|
||||
- do nset-nth, nremove-nth, nsubstitute, ninject
|
||||
- IN: format base: work with all types of numbers
|
||||
- bitwise operations
|
||||
|
||||
- tail call optimization broken again
|
||||
- rethink strhead/strtail&co
|
||||
|
||||
+ listener:
|
||||
+ listener/plugin:
|
||||
|
||||
- backspace overzealous
|
||||
- completion
|
||||
- fedit broken with listener
|
||||
- maple-like: press enter at old commands to evaluate there
|
||||
|
||||
+ native:
|
||||
|
||||
- SIGBUS handler
|
||||
- handle division by zero
|
||||
- broken pipe errors with httpd and telnetd in cfactor
|
||||
- read#
|
||||
- to_fixnum and friends: error on float
|
||||
ERROR: I/O error: [ "primitive_read_line_fd_8" "Resource temporarily unavailable" ]
|
||||
- errors: don't show .factor-rc
|
||||
- parsing should be parsing
|
||||
- describe-word
|
||||
- contains ==> contains?
|
||||
- telnetd: send errors on socket
|
||||
- inspector: sort
|
||||
- accept: return socket, instead of printing msg
|
||||
- enforce bottom-up in native bootstrap
|
||||
|
||||
+ interactive:
|
||||
|
@ -66,8 +67,9 @@ ERROR: I/O error: [ "primitive_read_line_fd_8" "Resource temporarily unavailable
|
|||
- inspector links when describe called without object path
|
||||
- 'cascading' styles
|
||||
|
||||
+ compiler:
|
||||
+ JVM compiler:
|
||||
|
||||
- tail call optimization broken again
|
||||
- don't compile inline words
|
||||
- recursive words with code after ifte
|
||||
- less unnecessary args to auxiliary methods
|
||||
|
@ -78,7 +80,6 @@ ERROR: I/O error: [ "primitive_read_line_fd_8" "Resource temporarily unavailable
|
|||
|
||||
+ misc:
|
||||
|
||||
- telnetd: needs own history
|
||||
- compiled stack traces broken
|
||||
- namespace clone drops static var bindings
|
||||
- ditch map
|
||||
|
@ -88,7 +89,6 @@ ERROR: I/O error: [ "primitive_read_line_fd_8" "Resource temporarily unavailable
|
|||
|
||||
+ httpd:
|
||||
|
||||
- multitasking
|
||||
- httpd: don't flush so much
|
||||
- log with date
|
||||
- log user agent
|
||||
|
|
|
@ -77,7 +77,7 @@ public class FactorParseException extends FactorException
|
|||
return position;
|
||||
}
|
||||
|
||||
public String getMessage()
|
||||
public String getParserMessage()
|
||||
{
|
||||
return msg;
|
||||
}
|
||||
|
|
|
@ -50,7 +50,6 @@ IN: kernel
|
|||
DEFER: getenv
|
||||
DEFER: setenv
|
||||
DEFER: save-image
|
||||
DEFER: handle?
|
||||
DEFER: room
|
||||
DEFER: os-env
|
||||
DEFER: type-of
|
||||
|
@ -60,8 +59,10 @@ IN: strings
|
|||
DEFER: str=
|
||||
DEFER: str-hashcode
|
||||
DEFER: sbuf=
|
||||
DEFER: clone-sbuf
|
||||
|
||||
IN: io-internals
|
||||
DEFER: port?
|
||||
DEFER: open-file
|
||||
DEFER: server-socket
|
||||
DEFER: close-fd
|
||||
|
@ -69,7 +70,6 @@ DEFER: accept-fd
|
|||
DEFER: read-line-fd-8
|
||||
DEFER: write-fd-8
|
||||
DEFER: flush-fd
|
||||
DEFER: shutdown-fd
|
||||
|
||||
IN: parser
|
||||
DEFER: str>float
|
||||
|
@ -125,6 +125,7 @@ IN: cross-compiler
|
|||
set-sbuf-nth
|
||||
sbuf-append
|
||||
sbuf>str
|
||||
clone-sbuf
|
||||
sbuf=
|
||||
number?
|
||||
>fixnum
|
||||
|
@ -205,7 +206,7 @@ IN: cross-compiler
|
|||
callstack
|
||||
set-datastack
|
||||
set-callstack
|
||||
handle?
|
||||
port?
|
||||
exit*
|
||||
server-socket
|
||||
close-fd
|
||||
|
|
|
@ -32,6 +32,7 @@ IN: kernel
|
|||
USE: arithmetic
|
||||
USE: combinators
|
||||
USE: errors
|
||||
USE: io-internals
|
||||
USE: lists
|
||||
USE: logic
|
||||
USE: namespaces
|
||||
|
@ -70,6 +71,7 @@ USE: unparser
|
|||
[
|
||||
[ cons? ] [ clone-list ]
|
||||
[ vector? ] [ clone-vector ]
|
||||
[ sbuf? ] [ clone-sbuf ]
|
||||
[ drop t ] [ ( return the object ) ]
|
||||
] cond ;
|
||||
|
||||
|
@ -87,7 +89,7 @@ USE: unparser
|
|||
[ vector? ] [ drop "vector" ]
|
||||
[ string? ] [ drop "string" ]
|
||||
[ sbuf? ] [ drop "sbuf" ]
|
||||
[ handle? ] [ drop "handle" ]
|
||||
[ port? ] [ drop "port" ]
|
||||
[ drop t ] [ drop "unknown" ]
|
||||
] cond ;
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ void primitive_to_rect(void)
|
|||
dpush(tag_fixnum(0));
|
||||
break;
|
||||
case COMPLEX_TYPE:
|
||||
c = untag_complex(dpeek());
|
||||
c = untag_complex(dpop());
|
||||
dpush(c->real);
|
||||
dpush(c->imaginary);
|
||||
break;
|
||||
|
|
|
@ -7,7 +7,7 @@ void init_io(void)
|
|||
env.user[STDOUT_ENV] = port(1);
|
||||
set_nonblocking(1);
|
||||
env.user[STDERR_ENV] = port(2);
|
||||
set_nonblocking(2);
|
||||
/* set_nonblocking(2); */
|
||||
}
|
||||
|
||||
/* Return true if something was read */
|
||||
|
@ -126,10 +126,11 @@ bool write_step(PORT* port)
|
|||
/* keep writing to the stream until everything is written */
|
||||
void flush_buffer(PORT* port)
|
||||
{
|
||||
IO_TASK* task;
|
||||
if(port->buf_mode != B_WRITE || port->buf_fill == 0)
|
||||
return;
|
||||
|
||||
add_io_task(IO_TASK_WRITE,port,F);
|
||||
task = add_io_task(IO_TASK_WRITE,port,F);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
|
|
118
native/iomux.c
118
native/iomux.c
|
@ -21,81 +21,55 @@ void init_iomux(void)
|
|||
init_io_tasks(&write_fd_set,write_io_tasks);
|
||||
}
|
||||
|
||||
void add_io_task_impl(
|
||||
IO_TASK* add_io_task_impl(
|
||||
IO_TASK_TYPE type,
|
||||
PORT* port,
|
||||
CELL callback,
|
||||
fd_set* fdset,
|
||||
IO_TASK* io_tasks,
|
||||
int* fd_count)
|
||||
{
|
||||
int fds = *fd_count;
|
||||
int fd = port->fd;
|
||||
|
||||
/* Look for an empty slot first */
|
||||
int i;
|
||||
for(i = 0; i < fds; i++)
|
||||
{
|
||||
if(io_tasks[i].port == F)
|
||||
{
|
||||
FD_SET(port->fd,fdset);
|
||||
io_tasks[i].type = type;
|
||||
io_tasks[i].port = tag_object(port);
|
||||
io_tasks[i].callback = callback;
|
||||
return;
|
||||
}
|
||||
}
|
||||
io_tasks[fd].type = type;
|
||||
io_tasks[fd].port = tag_object(port);
|
||||
io_tasks[fd].callback = callback;
|
||||
|
||||
/* add at end */
|
||||
if(fds == FD_SETSIZE)
|
||||
critical_error("Too many I/O tasks",*fd_count);
|
||||
if(fd >= *fd_count)
|
||||
*fd_count = fd + 1;
|
||||
|
||||
FD_SET(port->fd,fdset);
|
||||
io_tasks[fds].type = type;
|
||||
io_tasks[fds].port = tag_object(port);
|
||||
io_tasks[fds].callback = callback;
|
||||
*fd_count = fds + 1;
|
||||
return &io_tasks[fd];
|
||||
}
|
||||
|
||||
void add_io_task(IO_TASK_TYPE type, PORT* port, CELL callback)
|
||||
IO_TASK* add_io_task(IO_TASK_TYPE type, PORT* port, CELL callback)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case IO_TASK_READ_LINE:
|
||||
case IO_TASK_READ_COUNT:
|
||||
add_io_task_impl(type,port,callback,
|
||||
&read_fd_set,read_io_tasks,
|
||||
&read_fd_count);
|
||||
break;
|
||||
return add_io_task_impl(type,port,callback,
|
||||
read_io_tasks,&read_fd_count);
|
||||
case IO_TASK_WRITE:
|
||||
add_io_task_impl(type,port,callback,
|
||||
&write_fd_set,write_io_tasks,
|
||||
&write_fd_count);
|
||||
break;
|
||||
return add_io_task_impl(type,port,callback,
|
||||
write_io_tasks,&write_fd_count);
|
||||
default:
|
||||
fatal_error("Invalid IO_TASK_TYPE",type);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void remove_io_task_impl(
|
||||
IO_TASK_TYPE type,
|
||||
PORT* port,
|
||||
fd_set* fdset,
|
||||
IO_TASK* io_tasks,
|
||||
int* fd_count)
|
||||
{
|
||||
int i;
|
||||
int fds = *fd_count;
|
||||
int fd = port->fd;
|
||||
|
||||
for(i = 0; i < fds; i++)
|
||||
{
|
||||
if(untag_port(io_tasks[i].port) == port)
|
||||
{
|
||||
FD_CLR(port->fd,fdset);
|
||||
io_tasks[i].port = F;
|
||||
io_tasks[i].callback = F;
|
||||
if(i == fds - 1)
|
||||
*fd_count = fds - 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
io_tasks[fd].port = F;
|
||||
io_tasks[fd].callback = F;
|
||||
|
||||
if(fd == *fd_count - 1)
|
||||
*fd_count = *fd_count - 1;
|
||||
}
|
||||
|
||||
void remove_io_task(IO_TASK_TYPE type, PORT* port)
|
||||
|
@ -104,18 +78,15 @@ void remove_io_task(IO_TASK_TYPE type, PORT* port)
|
|||
{
|
||||
case IO_TASK_READ_LINE:
|
||||
case IO_TASK_READ_COUNT:
|
||||
remove_io_task_impl(type,port,
|
||||
&read_fd_set,read_io_tasks,
|
||||
&read_fd_count);
|
||||
remove_io_task_impl(type,port,read_io_tasks,&read_fd_count);
|
||||
break;
|
||||
case IO_TASK_WRITE:
|
||||
remove_io_task_impl(type,port,
|
||||
&write_fd_set,write_io_tasks,
|
||||
&write_fd_count);
|
||||
remove_io_task_impl(type,port,write_io_tasks,&write_fd_count);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void perform_iotask(IO_TASK* task)
|
||||
void perform_io_task(IO_TASK* task)
|
||||
{
|
||||
if(task->port == F)
|
||||
return;
|
||||
|
@ -134,20 +105,43 @@ void perform_iotask(IO_TASK* task)
|
|||
}
|
||||
}
|
||||
|
||||
bool set_up_fd_set(fd_set* fdset, IO_TASK* io_tasks)
|
||||
{
|
||||
bool retval = false;
|
||||
|
||||
int i;
|
||||
for(i = 0; i < read_fd_count; i++)
|
||||
{
|
||||
if(read_io_tasks[i].port != F)
|
||||
{
|
||||
retval = true;
|
||||
FD_SET(i,&read_fd_set);
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Wait for I/O and return a callback. */
|
||||
CELL iomux(void)
|
||||
{
|
||||
int nfds = select(read_fd_count > write_fd_count
|
||||
bool reading = set_up_fd_set(&read_fd_set,read_io_tasks);
|
||||
bool writing = set_up_fd_set(&write_fd_set,write_io_tasks);
|
||||
|
||||
if(!reading && !writing)
|
||||
fatal_error("iomux() called with no IO tasks",0);
|
||||
|
||||
select(read_fd_count > write_fd_count
|
||||
? read_fd_count : write_fd_count,
|
||||
&read_fd_set,&write_fd_set,NULL,NULL);
|
||||
(reading ? &read_fd_set : NULL),
|
||||
(writing ? &write_fd_set : NULL),
|
||||
NULL,NULL);
|
||||
|
||||
/* int i;
|
||||
|
||||
for(i = 0; i < read_fd_count; i++)
|
||||
perform_iotask(&read_io_tasks[i]);
|
||||
/* for(i = 0; i < read_fd_count; i++)
|
||||
perform_io_task(&read_io_tasks[i]);
|
||||
|
||||
for(i = 0; i < write_fd_count; i++)
|
||||
perform_iotask(&write_io_tasks[i]); */
|
||||
perform_io_task(&write_io_tasks[i]); */
|
||||
|
||||
return F;
|
||||
}
|
||||
|
|
|
@ -20,20 +20,20 @@ int write_fd_count;
|
|||
|
||||
void init_io_tasks(fd_set* fd_set, IO_TASK* io_tasks);
|
||||
void init_iomux(void);
|
||||
void add_io_task_impl(
|
||||
IO_TASK* add_io_task_impl(
|
||||
IO_TASK_TYPE type,
|
||||
PORT* port,
|
||||
CELL callback,
|
||||
fd_set* fdset,
|
||||
IO_TASK* io_tasks,
|
||||
int* fd_count);
|
||||
void add_io_task(IO_TASK_TYPE type, PORT* port, CELL callback);
|
||||
IO_TASK* add_io_task(IO_TASK_TYPE type, PORT* port, CELL callback);
|
||||
void remove_io_task_impl(
|
||||
IO_TASK_TYPE type,
|
||||
PORT* port,
|
||||
fd_set* fdset,
|
||||
IO_TASK* io_tasks,
|
||||
int* fd_count);
|
||||
void remove_io_task(IO_TASK_TYPE type, PORT* port);
|
||||
void perform_io_task(IO_TASK* task);
|
||||
bool set_up_fd_set(fd_set* fdset, IO_TASK* io_tasks);
|
||||
CELL iomux(void);
|
||||
void collect_io_tasks(void);
|
||||
|
|
|
@ -34,6 +34,7 @@ XT primitives[] = {
|
|||
primitive_set_sbuf_nth,
|
||||
primitive_sbuf_append,
|
||||
primitive_sbuf_to_string,
|
||||
primitive_clone_sbuf,
|
||||
primitive_sbuf_eq,
|
||||
primitive_numberp,
|
||||
primitive_to_fixnum,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
extern XT primitives[];
|
||||
#define PRIMITIVE_COUNT 128
|
||||
#define PRIMITIVE_COUNT 129
|
||||
|
||||
CELL primitive_to_xt(CELL primitive);
|
||||
|
|
|
@ -114,6 +114,14 @@ void primitive_sbuf_to_string(void)
|
|||
drepl(tag_object(sbuf_to_string(untag_sbuf(dpeek()))));
|
||||
}
|
||||
|
||||
void primitive_clone_sbuf(void)
|
||||
{
|
||||
SBUF* s = untag_sbuf(dpeek());
|
||||
SBUF* new_s = sbuf(s->top);
|
||||
sbuf_append_string(new_s,s->string);
|
||||
drepl(tag_object(new_s));
|
||||
}
|
||||
|
||||
bool sbuf_eq(SBUF* s1, SBUF* s2)
|
||||
{
|
||||
if(s1->top == s2->top)
|
||||
|
|
|
@ -27,6 +27,7 @@ void sbuf_append_string(SBUF* sbuf, STRING* string);
|
|||
void primitive_sbuf_append(void);
|
||||
STRING* sbuf_to_string(SBUF* sbuf);
|
||||
void primitive_sbuf_to_string(void);
|
||||
void primitive_clone_sbuf(void);
|
||||
bool sbuf_eq(SBUF* s1, SBUF* s2);
|
||||
void primitive_sbuf_eq(void);
|
||||
void fixup_sbuf(SBUF* sbuf);
|
||||
|
|
Loading…
Reference in New Issue