summaryrefslogtreecommitdiff
path: root/sys/src/ape
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@gmx.de>2013-03-11 00:48:35 +0100
committercinap_lenrek <cinap_lenrek@gmx.de>2013-03-11 00:48:35 +0100
commit48b0c10681bb4e0785fa9f737d287531d06fecb7 (patch)
tree568f7cdd23400f1e781b82aa044ad39748ff9d78 /sys/src/ape
parent530a2bc5e99ad83c46ce015544cf30173c145bcc (diff)
ape/stdio: make fopen() quasi threadsafe for python
python uses processes sharing memory. it requires at least fopen() to be called by multiple threads at once so we introduce _IO_newfile() which allocates the FILE structure slot under a lock.
Diffstat (limited to 'sys/src/ape')
-rw-r--r--sys/src/ape/lib/ap/stdio/_IO_getc.c3
-rw-r--r--sys/src/ape/lib/ap/stdio/_IO_newfile.c27
-rw-r--r--sys/src/ape/lib/ap/stdio/_IO_putc.c3
-rw-r--r--sys/src/ape/lib/ap/stdio/fclose.c22
-rw-r--r--sys/src/ape/lib/ap/stdio/fdopen.c6
-rw-r--r--sys/src/ape/lib/ap/stdio/fflush.c3
-rw-r--r--sys/src/ape/lib/ap/stdio/fopen.c9
-rw-r--r--sys/src/ape/lib/ap/stdio/fread.c5
-rw-r--r--sys/src/ape/lib/ap/stdio/fwrite.c8
-rw-r--r--sys/src/ape/lib/ap/stdio/iolib.h1
-rw-r--r--sys/src/ape/lib/ap/stdio/mkfile1
-rw-r--r--sys/src/ape/lib/ap/stdio/rdline.c5
-rw-r--r--sys/src/ape/lib/ap/stdio/sopenr.c5
-rw-r--r--sys/src/ape/lib/ap/stdio/sopenw.c5
14 files changed, 79 insertions, 24 deletions
diff --git a/sys/src/ape/lib/ap/stdio/_IO_getc.c b/sys/src/ape/lib/ap/stdio/_IO_getc.c
index 3f99922c2..fbd126df3 100644
--- a/sys/src/ape/lib/ap/stdio/_IO_getc.c
+++ b/sys/src/ape/lib/ap/stdio/_IO_getc.c
@@ -8,7 +8,7 @@ int _IO_getc(FILE *f){
default: /* CLOSED, WR, ERR, EOF */
return EOF;
case OPEN:
- _IO_setvbuf(f);
+ if(_IO_setvbuf(f)!=0) return EOF;
case RDWR:
case RD:
if(f->flags&STRING) return EOF;
@@ -17,6 +17,7 @@ int _IO_getc(FILE *f){
else
n = f->bufl;
cnt=read(f->fd, f->buf, n);
+ if(f->state==CLOSED) return EOF;
switch(cnt){
case -1: f->state=ERR; return EOF;
case 0: f->state=END; return EOF;
diff --git a/sys/src/ape/lib/ap/stdio/_IO_newfile.c b/sys/src/ape/lib/ap/stdio/_IO_newfile.c
new file mode 100644
index 000000000..6a016ec5d
--- /dev/null
+++ b/sys/src/ape/lib/ap/stdio/_IO_newfile.c
@@ -0,0 +1,27 @@
+/*
+ * pANS stdio -- fopen
+ */
+#include "iolib.h"
+
+#define _PLAN9_SOURCE
+#include <lock.h>
+
+FILE *_IO_newfile(void)
+{
+ static FILE *fx=0;
+ static Lock fl;
+ FILE *f;
+ int i;
+
+ lock(&fl);
+ for(i=0; i<FOPEN_MAX; i++){
+ if(fx==0 || ++fx >= &_IO_stream[FOPEN_MAX]) fx=_IO_stream;
+ if(fx->state==CLOSED)
+ break;
+ }
+ f = fx;
+ unlock(&fl);
+ if(f->state!=CLOSED)
+ return NULL;
+ return f;
+}
diff --git a/sys/src/ape/lib/ap/stdio/_IO_putc.c b/sys/src/ape/lib/ap/stdio/_IO_putc.c
index 8cef77fd3..375b43eb0 100644
--- a/sys/src/ape/lib/ap/stdio/_IO_putc.c
+++ b/sys/src/ape/lib/ap/stdio/_IO_putc.c
@@ -19,7 +19,8 @@ int _IO_putc(int c, FILE *f){
case CLOSED:
return EOF;
case OPEN:
- _IO_setvbuf(f);
+ if(_IO_setvbuf(f)!=0)
+ return EOF;
/* fall through */
case RDWR:
case END:
diff --git a/sys/src/ape/lib/ap/stdio/fclose.c b/sys/src/ape/lib/ap/stdio/fclose.c
index d14e83746..c3b157022 100644
--- a/sys/src/ape/lib/ap/stdio/fclose.c
+++ b/sys/src/ape/lib/ap/stdio/fclose.c
@@ -3,12 +3,28 @@
*/
#include "iolib.h"
int fclose(FILE *f){
- int error=0;
+ int d, error=0;
+ char *p;
+
if(!f) return EOF;
if(f->state==CLOSED) return EOF;
if(fflush(f)==EOF) error=EOF;
- if(f->flags&BALLOC) free(f->buf);
- if(!(f->flags&STRING) && close(f->fd)<0) error=EOF;
+ if(f->flags&BALLOC){
+ if((p = f->buf)!=0){
+ f->buf = 0;
+ f->wp = 0;
+ f->rp = 0;
+ f->lp = 0;
+ free(p);
+ }
+ }
+ if(!(f->flags&STRING)){
+ if((d = f->fd)>=0){
+ f->fd = -1;
+ if(close(d) < 0)
+ error = EOF;
+ }
+ }
f->state=CLOSED;
f->flags=0;
return error;
diff --git a/sys/src/ape/lib/ap/stdio/fdopen.c b/sys/src/ape/lib/ap/stdio/fdopen.c
index 0c585b965..cb10d98e7 100644
--- a/sys/src/ape/lib/ap/stdio/fdopen.c
+++ b/sys/src/ape/lib/ap/stdio/fdopen.c
@@ -14,10 +14,8 @@
*/
FILE *fdopen(const int fd, const char *mode){
FILE *f;
- for(f=_IO_stream;f!=&_IO_stream[FOPEN_MAX];f++)
- if(f->state==CLOSED)
- break;
- if(f==&_IO_stream[FOPEN_MAX])
+
+ if((f = _IO_newfile()) == NULL)
return NULL;
f->fd=fd;
if(mode[0]=='a')
diff --git a/sys/src/ape/lib/ap/stdio/fflush.c b/sys/src/ape/lib/ap/stdio/fflush.c
index 50a9da28f..28833f4c8 100644
--- a/sys/src/ape/lib/ap/stdio/fflush.c
+++ b/sys/src/ape/lib/ap/stdio/fflush.c
@@ -21,7 +21,8 @@ int fflush(FILE *f){
case WR:
cnt=(f->flags&LINEBUF?f->lp:f->wp)-f->buf;
if(cnt && write(f->fd, f->buf, cnt)!=cnt){
- f->state=ERR;
+ if(f->state!=CLOSED)
+ f->state=ERR;
return EOF;
}
f->rp=f->wp=f->buf;
diff --git a/sys/src/ape/lib/ap/stdio/fopen.c b/sys/src/ape/lib/ap/stdio/fopen.c
index edf27172c..a10da3a42 100644
--- a/sys/src/ape/lib/ap/stdio/fopen.c
+++ b/sys/src/ape/lib/ap/stdio/fopen.c
@@ -2,10 +2,11 @@
* pANS stdio -- fopen
*/
#include "iolib.h"
+
FILE *fopen(const char *name, const char *mode){
FILE *f;
- for(f=_IO_stream;f!=&_IO_stream[FOPEN_MAX];f++)
- if(f->state==CLOSED)
- return freopen(name, mode, f);
- return NULL;
+
+ if((f = _IO_newfile()) == NULL)
+ return NULL;
+ return freopen(name, mode, f);
}
diff --git a/sys/src/ape/lib/ap/stdio/fread.c b/sys/src/ape/lib/ap/stdio/fread.c
index c064a5649..1b54af2c6 100644
--- a/sys/src/ape/lib/ap/stdio/fread.c
+++ b/sys/src/ape/lib/ap/stdio/fread.c
@@ -12,7 +12,7 @@ size_t fread(void *p, size_t recl, size_t nrec, FILE *f){
s=(char *)p;
n=recl*nrec;
- while(n>0){
+ while(n>0 && f->state!=CLOSED){
d=f->wp-f->rp;
if(d>0){
if(d>n)
@@ -23,7 +23,8 @@ size_t fread(void *p, size_t recl, size_t nrec, FILE *f){
if(f->buf==f->unbuf || (n >= BIGN && f->state==RD && !(f->flags&STRING))){
d=read(f->fd, s, n);
if(d<=0){
- f->state=(d==0)?END:ERR;
+ if(f->state!=CLOSED)
+ f->state=(d==0)?END:ERR;
goto ret;
}
}else{
diff --git a/sys/src/ape/lib/ap/stdio/fwrite.c b/sys/src/ape/lib/ap/stdio/fwrite.c
index 4dc18d99e..2ec20cae5 100644
--- a/sys/src/ape/lib/ap/stdio/fwrite.c
+++ b/sys/src/ape/lib/ap/stdio/fwrite.c
@@ -12,7 +12,7 @@ size_t fwrite(const void *p, size_t recl, size_t nrec, FILE *f){
s=(char *)p;
n=recl*nrec;
- while(n>0){
+ while(n>0 && f->state!=CLOSED){
d=f->rp-f->wp;
if(d>0){
if(d>n)
@@ -26,7 +26,8 @@ size_t fwrite(const void *p, size_t recl, size_t nrec, FILE *f){
if(f->flags&APPEND)
lseek(f->fd, 0L, SEEK_END);
if(write(f->fd, f->buf, d)!=d){
- f->state=ERR;
+ if(f->state!=CLOSED)
+ f->state=ERR;
goto ret;
}
f->wp=f->rp=f->buf;
@@ -35,7 +36,8 @@ size_t fwrite(const void *p, size_t recl, size_t nrec, FILE *f){
lseek(f->fd, 0L, SEEK_END);
d=write(f->fd, s, n);
if(d<=0){
- f->state=ERR;
+ if(f->state!=CLOSED)
+ f->state=ERR;
goto ret;
}
} else {
diff --git a/sys/src/ape/lib/ap/stdio/iolib.h b/sys/src/ape/lib/ap/stdio/iolib.h
index 3a5bd63a0..57eb96085 100644
--- a/sys/src/ape/lib/ap/stdio/iolib.h
+++ b/sys/src/ape/lib/ap/stdio/iolib.h
@@ -42,3 +42,4 @@ int _IO_setvbuf(FILE *);
FILE *_IO_sopenr(const char*);
FILE *_IO_sopenw(void);
char *_IO_sclose(FILE *);
+FILE *_IO_newfile(void);
diff --git a/sys/src/ape/lib/ap/stdio/mkfile b/sys/src/ape/lib/ap/stdio/mkfile
index 17be0da58..76e51b27b 100644
--- a/sys/src/ape/lib/ap/stdio/mkfile
+++ b/sys/src/ape/lib/ap/stdio/mkfile
@@ -2,6 +2,7 @@ APE=/sys/src/ape
<$APE/config
LIB=/$objtype/lib/ape/libap.a
OFILES=\
+ _IO_newfile.$O\
_IO_getc.$O\
_IO_putc.$O\
_dtoa.$O\
diff --git a/sys/src/ape/lib/ap/stdio/rdline.c b/sys/src/ape/lib/ap/stdio/rdline.c
index 6281a97e8..dafe71da4 100644
--- a/sys/src/ape/lib/ap/stdio/rdline.c
+++ b/sys/src/ape/lib/ap/stdio/rdline.c
@@ -12,7 +12,8 @@ char *rdline(FILE *f, char **ep){
default: /* CLOSED, WR, ERR, EOF */
return NULL;
case OPEN:
- _IO_setvbuf(f);
+ if(_IO_setvbuf(f)!=0)
+ return NULL;
case RDWR:
f->state=RD;
case RD:
@@ -46,6 +47,8 @@ char *rdline(FILE *f, char **ep){
break;
}
cnt=read(f->fd, f->wp, cnt);
+ if(f->state==CLOSED)
+ return NULL;
if(cnt==-1){
f->state=ERR;
return NULL;
diff --git a/sys/src/ape/lib/ap/stdio/sopenr.c b/sys/src/ape/lib/ap/stdio/sopenr.c
index 279ec726b..964493abf 100644
--- a/sys/src/ape/lib/ap/stdio/sopenr.c
+++ b/sys/src/ape/lib/ap/stdio/sopenr.c
@@ -6,8 +6,9 @@
FILE *_IO_sopenr(const char *s){
FILE *f;
- for(f=_IO_stream;f!=&_IO_stream[FOPEN_MAX];f++) if(f->state==CLOSED) break;
- if(f==&_IO_stream[FOPEN_MAX]) return NULL;
+
+ if((f=_IO_newfile())==NULL)
+ return NULL;
f->buf=f->rp=(char *)s; /* what an annoyance const is */
f->bufl=strlen(s);
f->wp=f->buf+f->bufl;
diff --git a/sys/src/ape/lib/ap/stdio/sopenw.c b/sys/src/ape/lib/ap/stdio/sopenw.c
index d13634333..4973da357 100644
--- a/sys/src/ape/lib/ap/stdio/sopenw.c
+++ b/sys/src/ape/lib/ap/stdio/sopenw.c
@@ -5,8 +5,9 @@
FILE *_IO_sopenw(void){
FILE *f;
- for(f=_IO_stream;f!=&_IO_stream[FOPEN_MAX];f++) if(f->state==CLOSED) break;
- if(f==&_IO_stream[FOPEN_MAX]) return NULL;
+
+ if((f=_IO_newfile())==NULL)
+ return NULL;
f->buf=f->rp=f->wp=0;
f->state=OPEN;
f->flags=STRING;