shithub: lpa

ref: ee1ed56428b090dd694f50b49f4957c4d2e11bc2
dir: /session.c/

View raw version
#include <u.h>
#include <libc.h>
#include <thread.h>

#include "dat.h"
#include "fns.h"

typedef struct SessionList SessionList;
struct SessionList
{
	uvlong count;
	Session **sessions;
};

SessionList *sessions;

void
appendlog(Session *s, char *data)
{
	uvlong size = strlen(data);
	qlock(&s->loglock);
	s->logsize += size;
	s->log = allocextra(s, s->logsize);
	memcpy(&s->log[s->logsize-size], data, size);
	s->qlog.vers++;
	rwakeupall(&s->logwait);
	qunlock(&s->loglock);
}

static void
sessionproc(void *arg)
{
	char *prompt = "      "; /* 6-space prompt */
	char *buf = nil;
	Session *s = arg;
	while(1){
		appendlog(s, prompt);

		free(buf);
		recv(s->input, &buf);
		appendlog(s, buf);

		if(strlen(buf) > 0 && buf[0] == ')')
			systemcmd(s, buf+1, 0);
		else{
			char *err = nil;
			TokenList *tokens = scan(buf, &err);
			if(err){
error:
				appendlog(s, err);
				appendlog(s, "\n");
				continue;
			}
			
			Ast *ast = parse(tokens, 0, &err);
			if(err)
				goto error;

			debugast(ast, 0);
			void *val = eval(s, ast);
			if(val)
				appendlog(s, printval(val));
		}
	}
}

Session *
allocsession(void)
{
	static uvlong id = 1;

	Session *s = alloc(DataSession);

	s->id = id++;
	s->name = smprint("%ulld", s->id);
	s->active = 1;

	s->logwait.l = &s->loglock;
	s->logsize = 0;
	s->log = nil;

	s->modules = alloc(DataModuleList);

	s->input = chancreate(sizeof(char *), 0);

	sessions->count++;
	sessions->sessions = allocextra(sessions, sizeof(Session *) * sessions->count);
	sessions->sessions[sessions->count-1] = s;

	proccreate(sessionproc, s, 1024*1024);

	return s;
}

Enumeration *
enumsessions(void)
{
	Enumeration *e = allocenum(sessions->count);
	for(uvlong i = 0; i < sessions->count; i++)
		e->items[i] = sessions->sessions[i];

	return e;
}

void
initsessions(void)
{
	dataspecs[DataSessionList].size = sizeof(SessionList);

	sessions = alloc(DataSessionList);
	setroot(sessions, 1);
}