Commit 4c8482c9 authored by rswindell's avatar rswindell
Browse files

Update the C getnodedat/putnodedat API to not require that the node file

(ctrl/node.dab) is constantly closed and re-opened for every non-locking read.
This is really slow across network file systems and unnecessary, so use a
similar optimization as the C++ sbbs_t class where the file can (and normally
is) left open across multiple consecutive reads.
Create/use opennodedat() function.
Uses the new CLOSE_OPEN_FILE() macro from xpdev/filewrap.h.
parent 5fbeebf8
......@@ -3558,7 +3558,7 @@ static void ctrl_thread(void* arg)
if(!stricmp(cmd, "SITE WHO")) {
sockprintf(sock,sess,"211-Active Telnet Nodes:");
for(i=0;i<scfg.sys_nodes && i<scfg.sys_lastnode;i++) {
if((result=getnodedat(&scfg, i+1, &node, 0))!=0) {
if((result=getnodedat(&scfg, i+1, &node, FALSE, NULL))!=0) {
sockprintf(sock,sess," Error %d getting data for Telnet Node %d",result,i+1);
continue;
}
......
......@@ -2014,7 +2014,7 @@ static JSBool js_node_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
rc=JS_SUSPENDREQUEST(cx);
memset(&node,0,sizeof(node));
if(getnodedat(cfg, node_num, &node, NULL)) {
if(getnodedat(cfg, node_num, &node, /* lockit: */FALSE, &cfg->nodefile)) {
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
}
......@@ -2058,7 +2058,6 @@ static JSBool js_node_set(JSContext *cx, JSObject *obj, jsid id, JSBool strict,
{
jsval idval;
uint node_num;
int file;
jsint val=0;
jsint tiny;
node_t node;
......@@ -2080,7 +2079,7 @@ static JSBool js_node_set(JSContext *cx, JSObject *obj, jsid id, JSBool strict,
rc=JS_SUSPENDREQUEST(cx);
memset(&node,0,sizeof(node));
if(getnodedat(cfg, node_num, &node, &file)) {
if(getnodedat(cfg, node_num, &node, /* lockit: */TRUE, &cfg->nodefile)) {
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
}
......@@ -2119,7 +2118,7 @@ static JSBool js_node_set(JSContext *cx, JSObject *obj, jsid id, JSBool strict,
node.extaux=val;
break;
}
putnodedat(cfg,node_num,&node,file);
putnodedat(cfg,node_num,&node, /* closeit: */FALSE, cfg->nodefile);
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
......@@ -2396,6 +2395,16 @@ static JSBool js_system_enumerate(JSContext *cx, JSObject *obj)
return(js_system_resolve(cx, obj, JSID_VOID));
}
static void js_system_finalize(JSContext *cx, JSObject *obj)
{
scfg_t* cfg;
if((cfg = (scfg_t*)JS_GetPrivate(cx, obj)) == NULL)
return;
CLOSE_OPEN_FILE(cfg->nodefile);
}
JSClass js_system_class = {
"System" /* name */
,JSCLASS_HAS_PRIVATE /* flags */
......@@ -2406,7 +2415,7 @@ JSClass js_system_class = {
,js_system_enumerate /* enumerate */
,js_system_resolve /* resolve */
,JS_ConvertStub /* convert */
,JS_FinalizeStub /* finalize */
,js_system_finalize /* finalize */
};
JSObject* DLLCALL js_CreateSystemObject(JSContext* cx, JSObject* parent
......@@ -2423,6 +2432,9 @@ JSObject* DLLCALL js_CreateSystemObject(JSContext* cx, JSObject* parent
if(sysobj==NULL)
return(NULL);
if(cfg->nodefile < 1) // An initialized scfg_t is usually all 0's
cfg->nodefile = -1;
if(!JS_SetPrivate(cx, sysobj, cfg)) /* Store a pointer to scfg_t */
return(NULL);
......
......@@ -3933,7 +3933,7 @@ static void smtp_thread(void* arg)
if(!(startup->options&MAIL_OPT_NO_NOTIFY) && usernum) {
if(newmsg.idx.to)
for(i=1;i<=scfg.sys_nodes;i++) {
getnodedat(&scfg, i, &node, 0);
getnodedat(&scfg, i, &node, FALSE, NULL);
if(node.useron==usernum
&& (node.status==NODE_INUSE || node.status==NODE_QUIET))
break;
......@@ -4816,7 +4816,7 @@ static void smtp_thread(void* arg)
}
else if(cmd==SMTP_CMD_SEND) { /* Check if user online */
for(i=0;i<scfg.sys_nodes;i++) {
getnodedat(&scfg, i+1, &node, 0);
getnodedat(&scfg, i+1, &node, FALSE, NULL);
if(node.status==NODE_INUSE && node.useron==user.number
&& !(node.misc&NODE_POFF))
break;
......
......@@ -2190,7 +2190,7 @@ int main(int argc, char** argv)
printf("\n");
count=0;
for(i=1;i<=scfg.sys_nodes;i++) {
getnodedat(&scfg,i,&node,NULL /* file */);
getnodedat(&scfg,i,&node, /* lockit: */FALSE, NULL /* file */);
if(ch=='w' && node.status!=NODE_INUSE && node.status!=NODE_QUIET)
continue;
printnodedat(&scfg, i,&node);
......@@ -2210,7 +2210,8 @@ int main(int argc, char** argv)
break;
fflush(stdin);
printf("\n");
if((i=getnodedat(&scfg,n,&node,&file))!=0) {
CLOSE_OPEN_FILE(file);
if((i=getnodedat(&scfg,n,&node, /* lockit: */TRUE, &file))!=0) {
printf("!Error %d getting node %d data\n",i,n);
break;
}
......@@ -2225,7 +2226,7 @@ int main(int argc, char** argv)
node.misc^=NODE_INTR;
break;
}
putnodedat(&scfg,n,&node,file);
putnodedat(&scfg,n,&node,/* closeit: */TRUE, file);
printnodedat(&scfg,n,&node);
#ifdef __unix__
_echo_off(); /* turn off echoing - failsafe */
......
......@@ -613,7 +613,9 @@ typedef struct
uint16_t user_backup_level;
uint16_t mail_backup_level;
// Run-time state information (not configuration)
int tls_certificate;
int nodefile;
} scfg_t;
......
......@@ -1096,16 +1096,17 @@ void DLLCALL refresh_cfg(scfg_t* cfg)
{
char str[MAX_PATH+1];
int i;
int file;
int file = -1;
node_t node;
for(i=0;i<cfg->sys_nodes;i++) {
if(getnodedat(cfg,i+1,&node,&file)!=0)
if(getnodedat(cfg,i+1,&node, /* lockit: */TRUE, &file)!=0)
continue;
node.misc|=NODE_RRUN;
if(putnodedat(cfg,i+1,&node,file))
if(putnodedat(cfg,i+1,&node, /* closeit: */FALSE, file))
break;
}
CLOSE_OPEN_FILE(file);
SAFEPRINTF(str,"%srecycle",cfg->ctrl_dir); ftouch(str);
}
......
......@@ -455,23 +455,24 @@ int fgetuserdat(scfg_t* cfg, user_t *user, int file)
/****************************************************************************/
static void dirtyuserdat(scfg_t* cfg, uint usernumber)
{
int i,file;
int i,file = -1;
node_t node;
for(i=1;i<=cfg->sys_nodes;i++) { /* instant user data update */
// if(i==cfg->node_num)
// continue;
if(getnodedat(cfg, i,&node,NULL) != 0)
if(getnodedat(cfg, i,&node, /* lockit: */FALSE, &file) != 0)
continue;
if(node.useron==usernumber && (node.status==NODE_INUSE
|| node.status==NODE_QUIET)) {
if(getnodedat(cfg, i,&node,&file) == 0) {
if(getnodedat(cfg, i,&node, /* lockit: */TRUE, &file) == 0) {
node.misc|=NODE_UDAT;
putnodedat(cfg, i,&node,file);
putnodedat(cfg, i,&node, /* closeit: */FALSE, file);
}
break;
}
}
CLOSE_OPEN_FILE(file);
}
/****************************************************************************/
......@@ -479,14 +480,17 @@ static void dirtyuserdat(scfg_t* cfg, uint usernumber)
int is_user_online(scfg_t* cfg, uint usernumber)
{
int i;
int file = -1;
node_t node;
for(i=1; i<=cfg->sys_nodes; i++) {
getnodedat(cfg, i, &node, 0);
getnodedat(cfg, i, &node, /* lockit: */FALSE, &file);
if((node.status==NODE_INUSE || node.status==NODE_QUIET
|| node.status==NODE_LOGON) && node.useron==usernumber)
return i;
}
if(file >= 0)
close(file);
return 0;
}
......@@ -766,28 +770,40 @@ uint getage(scfg_t* cfg, char *birth)
return(age);
}
/****************************************************************************/
/****************************************************************************/
int opennodedat(scfg_t* cfg)
{
char fname[MAX_PATH+1];
if(!VALID_CFG(cfg))
return -1;
SAFEPRINTF(fname, "%snode.dab", cfg->ctrl_dir);
return nopen(fname, O_RDWR|O_DENYNONE);
}
/****************************************************************************/
/* Reads the data for node number 'number' into the structure 'node' */
/* from node.dab */
/****************************************************************************/
int getnodedat(scfg_t* cfg, uint number, node_t *node, int* fdp)
int getnodedat(scfg_t* cfg, uint number, node_t *node, BOOL lockit, int* fdp)
{
char str[MAX_PATH+1];
int rd;
int count=0;
int file;
if(fdp!=NULL)
*fdp=-1;
if(!VALID_CFG(cfg)
|| node==NULL || number<1 || number>cfg->sys_nodes)
return(-1);
memset(node,0,sizeof(node_t));
SAFEPRINTF(str,"%snode.dab",cfg->ctrl_dir);
if((file=nopen(str,O_RDWR|O_DENYNONE))==-1)
return(errno);
if(fdp != NULL && *fdp > 0)
file = *fdp;
else {
if((file = opennodedat(cfg)) == -1)
return errno;
}
if(filelength(file)>=(long)(number*sizeof(node_t))) {
number--; /* make zero based */
......@@ -795,7 +811,7 @@ int getnodedat(scfg_t* cfg, uint number, node_t *node, int* fdp)
if(count)
mswait(100);
lseek(file,(long)number*sizeof(node_t),SEEK_SET);
if(fdp!=NULL
if(lockit
&& lock(file,(long)number*sizeof(node_t),sizeof(node_t))!=0)
continue;
rd=read(file,node,sizeof(node_t));
......@@ -820,7 +836,7 @@ int getnodedat(scfg_t* cfg, uint number, node_t *node, int* fdp)
/****************************************************************************/
/* Write the data from the structure 'node' into node.dab */
/****************************************************************************/
int putnodedat(scfg_t* cfg, uint number, node_t* node, int file)
int putnodedat(scfg_t* cfg, uint number, node_t* node, BOOL closeit, int file)
{
size_t wr=0;
int wrerr=0;
......@@ -843,7 +859,8 @@ int putnodedat(scfg_t* cfg, uint number, node_t* node, int file)
mswait(100);
}
unlock(file,(long)number*sizeof(node_t),sizeof(node_t));
close(file);
if(closeit)
close(file);
if(wr!=sizeof(node_t))
return(wrerr);
......@@ -1244,17 +1261,19 @@ int putsmsg(scfg_t* cfg, int usernumber, char *strin)
return(errno);
}
close(file);
file = -1;
for(i=1;i<=cfg->sys_nodes;i++) { /* flag node if user on that msg waiting */
getnodedat(cfg,i,&node,NULL);
getnodedat(cfg,i,&node,/* lockit: */FALSE, &file);
if(node.useron==usernumber
&& (node.status==NODE_INUSE || node.status==NODE_QUIET)
&& !(node.misc&NODE_MSGW)) {
if(getnodedat(cfg,i,&node,&file)==0) {
if(getnodedat(cfg,i,&node, /* lockit: */TRUE, &file)==0) {
node.misc|=NODE_MSGW;
putnodedat(cfg,i,&node,file);
putnodedat(cfg,i,&node, /* closeit: */FALSE, file);
}
}
}
CLOSE_OPEN_FILE(file);
return(0);
}
......@@ -1265,7 +1284,7 @@ char* getsmsg(scfg_t* cfg, int usernumber)
{
char str[MAX_PATH+1], *buf;
int i;
int file;
int file = -1;
long length;
node_t node;
......@@ -1273,16 +1292,17 @@ char* getsmsg(scfg_t* cfg, int usernumber)
return(NULL);
for(i=1;i<=cfg->sys_nodes;i++) { /* clear msg waiting flag */
getnodedat(cfg,i,&node,NULL);
getnodedat(cfg,i,&node, /* lockit: */FALSE, &file);
if(node.useron==usernumber
&& (node.status==NODE_INUSE || node.status==NODE_QUIET)
&& node.misc&NODE_MSGW) {
if(getnodedat(cfg,i,&node,&file) == 0) {
if(getnodedat(cfg,i,&node, /* lockit: */TRUE, &file) == 0) {
node.misc&=~NODE_MSGW;
putnodedat(cfg,i,&node,file);
putnodedat(cfg,i,&node, /* closeit: */FALSE, file);
}
}
}
CLOSE_OPEN_FILE(file);
SAFEPRINTF2(str,"%smsgs/%4.4u.msg",cfg->data_dir,usernumber);
if(flength(str)<1L)
......@@ -1311,16 +1331,16 @@ char* getnmsg(scfg_t* cfg, int node_num)
{
char str[MAX_PATH+1];
char* buf;
int file;
int file = -1;
long length;
node_t node;
if(!VALID_CFG(cfg) || node_num<1)
return(NULL);
if(getnodedat(cfg,node_num,&node,&file) == 0) {
if(getnodedat(cfg,node_num,&node, /* lockit: */TRUE, &file) == 0) {
node.misc&=~NODE_NMSG; /* clear the NMSG flag */
putnodedat(cfg,node_num,&node,file);
putnodedat(cfg,node_num,&node, /* closeit: */TRUE, file);
}
SAFEPRINTF2(str,"%smsgs/n%3.3u.msg",cfg->data_dir,node_num);
......@@ -1373,15 +1393,16 @@ int putnmsg(scfg_t* cfg, int num, char *strin)
close(file);
return(errno);
}
close(file);
getnodedat(cfg,num,&node,NULL);
CLOSE_OPEN_FILE(file);
getnodedat(cfg,num,&node, /* lockit: */FALSE, &file);
if((node.status==NODE_INUSE || node.status==NODE_QUIET)
&& !(node.misc&NODE_NMSG)) {
if(getnodedat(cfg,num,&node,&file) == 0) {
if(getnodedat(cfg,num,&node, /* lockit: */TRUE, &file) == 0) {
node.misc|=NODE_NMSG;
putnodedat(cfg,num,&node,file);
putnodedat(cfg,num,&node, /* closeit: */FALSE, file);
}
}
CLOSE_OPEN_FILE(file);
return(0);
}
......
......@@ -82,8 +82,9 @@ DLLEXPORT BOOL del_lastuser(scfg_t*);
DLLEXPORT uint getage(scfg_t*, char *birthdate);
DLLEXPORT char* username(scfg_t*, int usernumber, char * str);
DLLEXPORT char* usermailaddr(scfg_t*, char* addr, const char* name);
DLLEXPORT int getnodedat(scfg_t*, uint number, node_t *node, int* file);
DLLEXPORT int putnodedat(scfg_t*, uint number, node_t *node, int file);
DLLEXPORT int opennodedat(scfg_t*);
DLLEXPORT int getnodedat(scfg_t*, uint number, node_t *node, BOOL lockit, int* file);
DLLEXPORT int putnodedat(scfg_t*, uint number, node_t *node, BOOL closeit, int file);
DLLEXPORT char* nodestatus(scfg_t*, node_t* node, char* buf, size_t buflen);
DLLEXPORT void printnodedat(scfg_t*, uint number, node_t* node);
DLLEXPORT int is_user_online(scfg_t*, uint usernumber);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment