diff options
80 files changed, 2517 insertions, 733 deletions
diff --git a/toj/center/src/Makefile b/toj/center/src/Makefile index dcfab80..2c4f637 100644..100755 --- a/toj/center/src/Makefile +++ b/toj/center/src/Makefile @@ -2,14 +2,14 @@ ifneq ($(KERNELRELEASE),) judgk-objs := judgk_mod.o judgk_proc.o judgk_syscall.o judgk_syscall_asm.o judgk_security.o judgk_hyperio.o obj-m := judgk.o else - KERNEL_SOURCE := /usr/lib/modules/$(shell uname -r)/build + KERNEL_SOURCE := /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) default: ${MAKE} -C ${KERNEL_SOURCE} M=${PWD} modules mv judgk.ko ../judge/ - g++ -rdynamic -fvisibility=hidden -O2 center_server.cpp center_manage.cpp center_judge.cpp pack.cpp /srv/http/toj/php/event_exec.cpp -ldl -lpq -ltar -lbz2 -ljson -lcurl -pthread -o center_server - g++ -O2 judge_server.cpp pack.cpp -ldl -lbz2 -ltar -pthread -o judge_server + g++ -g -rdynamic -fvisibility=hidden -O2 center_server.cpp center_manage.cpp center_judge.cpp tool.cpp /srv/http/toj/php/event_exec.cpp -ldl -lpq -ltar -lbz2 -ljson -lcurl -pthread -o center_server + g++ -g -O2 judge_server.cpp judge_manage.cpp tool.cpp -ldl -lbz2 -ltar -pthread -o judge_server mv center_server ../ mv judge_server ../judge/ @@ -20,6 +20,7 @@ default: mv jmod_test_line.so ../jmod/jmod_test/ mv jmod_test_check.so ../jmod/jmod_test/ tar -jcvf ../tmp/jmodpack/jmod_test.tar.bz2 -C ../jmod/jmod_test . + clean: ${MAKE} -C ${KERNEL_SOURCE} SUBDIRS=${PWD} clean endif diff --git a/toj/center/src/center.h b/toj/center/src/center.h index a143df0..2625ab4 100644..100755 --- a/toj/center/src/center.h +++ b/toj/center/src/center.h @@ -1,3 +1,6 @@ +#define CENTER_CACHESTATE_READY 0 +#define CENTER_CACHESTATE_UPDATE 1 + class center_jmod_info{ public: char name[NAME_MAX + 1]; @@ -6,6 +9,10 @@ public: void *manage_sub_fn; void *manage_res_fn; + int ref_count; + int state; + int update_cacheid; + center_jmod_info(char *name,int cacheid){ this->name[0] = '\0'; strncat(this->name,name,sizeof(this->name)); @@ -23,31 +30,18 @@ public: center_jmod_info *jmod_info; int lang_flag; + int ref_count; + int state; + int update_cacheid; + center_pro_info(int proid,int cacheid,center_jmod_info *jmod_info,int lang_flag){ this->proid = proid; this->cacheid = cacheid; this->jmod_info = jmod_info; this->lang_flag = lang_flag; - } -}; -class center_submit_info{ -public: - int subid; - int uid; - center_jmod_info *jmod_info; - center_pro_info *pro_info; - int lang; - char *param; - void *jmod_manage_data; - - center_submit_info(int subid,int uid,center_jmod_info *jmod_info,center_pro_info *pro_info,int lang,char *param){ - this->subid = subid; - this->uid = uid; - this->jmod_info = jmod_info; - this->pro_info = pro_info; - this->lang = lang; - this->param = param; - this->jmod_manage_data = NULL; + this->ref_count = 0; + this->state = CENTER_CACHESTATE_READY; + this->update_cacheid = 0; } }; diff --git a/toj/center/src/center_com.h b/toj/center/src/center_com.h index 73f3ff3..6973eec 100644..100755 --- a/toj/center/src/center_com.h +++ b/toj/center/src/center_com.h @@ -23,11 +23,10 @@ struct center_com_setid{ struct center_com_setinfo{ int avail; }__attribute__((packed)); -struct center_com_submit{ +struct center_com_submit{ //judt submit header int subid; int proid; int lang; - char set_data[JUDGE_SET_DATAMAX]; }__attribute__((packed)); struct center_com_result{ //just result header int subid; @@ -40,6 +39,7 @@ struct center_com_setpro{ }__attribute__((packed)); struct center_com_reqpro{ int proid; + int cacheid; }__attribute__((packed)); struct center_com_sendpro{ int proid; diff --git a/toj/center/src/center_judge.cpp b/toj/center/src/center_judge.cpp index 38837cc..85a2fd6 100644..100755 --- a/toj/center/src/center_judge.cpp +++ b/toj/center/src/center_judge.cpp @@ -16,6 +16,7 @@ #include"netio.h" #include"judge_def.h" +#include"judgm_manage.h" #include"center.h" #include"center_com.h" #include"center_judge.h" @@ -68,7 +69,17 @@ int judge_info::result(int subid,char *res_data){ printf("submitid:%d\n",subid); center_manage_result(subid,res_data); - judge_submit_waitqueue(); + judge_run_waitqueue(); + return 0; +} +int judge_info::updatepro(std::vector<std::pair<int,int> > &pro_list){ + int i; + + for(i = 0;i < pro_list.size();i++){ + pro_map.erase(pro_list[i].first); + } + conn_main->send_setpro(pro_list,0); + return 0; } @@ -81,6 +92,7 @@ judge_conn::judge_conn(int fd):netio(fd){ this->recv_result_fn = new netio_iofn<judge_conn>(this,&judge_conn::recv_result); this->recv_setpro_fn = new netio_iofn<judge_conn>(this,&judge_conn::recv_setpro); this->recv_reqpro_fn = new netio_iofn<judge_conn>(this,&judge_conn::recv_reqpro); + this->done_sendpro_fn = new netio_iofn<judge_conn>(this,&judge_conn::done_sendpro); this->recv_setjmod_fn = new netio_iofn<judge_conn>(this,&judge_conn::recv_setjmod); this->recv_reqjmod_fn = new netio_iofn<judge_conn>(this,&judge_conn::recv_reqjmod); this->recv_reqcode_fn = new netio_iofn<judge_conn>(this,&judge_conn::recv_reqcode); @@ -100,6 +112,7 @@ judge_conn::~judge_conn(){ delete recv_result_fn; delete recv_setpro_fn; delete recv_reqpro_fn; + delete done_sendpro_fn; delete recv_setjmod_fn; delete recv_reqjmod_fn; delete recv_reqcode_fn; @@ -133,29 +146,35 @@ int judge_conn::send_submit(judge_submit_info *sub_info){ int write_len; center_com_submit *sub; - printf(" send submit %d\n",sub_info->subid); + if(sub_info->set_len > JUDGE_SET_DATAMAX){ + delete sub_info; + return -1; + } - write_buf = create_combuf(CENTER_COMCODE_SUBMIT,sizeof(center_com_submit),write_len,(void**)&sub); + write_buf = create_combuf(CENTER_COMCODE_SUBMIT,sizeof(center_com_submit) + sub_info->set_len,write_len,(void**)&sub); sub->subid = sub_info->subid; sub->proid = sub_info->proid; sub->lang = sub_info->lang; - memcpy(sub->set_data,sub_info->set_data,sub_info->set_len); + memcpy((void*)(write_buf + sizeof(center_com_header) + sizeof(center_com_submit)),sub_info->set_data,sub_info->set_len); writebytes(write_buf,write_len,NULL,NULL); delete sub_info; return 0; } -int judge_conn::send_setpro(int *proid,int *cacheid,int type,int count){ +int judge_conn::send_setpro(std::vector<std::pair<int,int> > &pro_list,int type){ int i; + int count; char *write_buf; int write_len; center_com_setpro *setpro; + count = pro_list.size(); write_buf = create_combuf(CENTER_COMCODE_SETPRO,sizeof(center_com_setpro) * count,write_len,(void**)&setpro); + for(i = 0;i < count;i++){ - setpro[i].proid = proid[i]; - setpro[i].cacheid = cacheid[i]; + setpro[i].proid = pro_list[i].first; + setpro[i].cacheid = pro_list[i].second; setpro[i].type = type; } writebytes(write_buf,write_len,NULL,NULL); @@ -251,7 +270,7 @@ void judge_conn::recv_setinfo(void *buf,size_t len,void *data){ center_com_setinfo *setinfo; char **jmod_name; std::map<std::string,center_jmod_info*>::iterator jmod_it; - int *proid; + std::vector<std::pair<int,int> > pro_list; int *cacheid; std::map<int,center_pro_info*>::iterator pro_it; @@ -272,17 +291,11 @@ void judge_conn::recv_setinfo(void *buf,size_t len,void *data){ delete cacheid; count = center_manage_promap.size(); - proid = new int[count]; - cacheid = new int[count]; pro_it = center_manage_promap.begin(); for(i = 0;i < count;i++,pro_it++){ - proid[i] = pro_it->second->proid; - cacheid[i] = pro_it->second->cacheid; + pro_list.push_back(std::make_pair(pro_it->second->proid,pro_it->second->cacheid)); } - send_setpro(proid,cacheid,0,count); - - delete proid; - delete cacheid; + send_setpro(pro_list,0); delete setinfo; } @@ -302,26 +315,28 @@ void judge_conn::recv_setpro(void *buf,size_t len,void *data){ int count; center_com_setpro *setpro; + center_pro_info *pro_info; std::map<int,center_pro_info*>::iterator pro_it; count = len / sizeof(center_com_setpro); setpro = (center_com_setpro*)buf; for(i = 0;i < count;i++){ if(setpro[i].type == 0){ - if((pro_it = center_manage_promap.find(setpro[i].proid)) == center_manage_promap.end()){ + if((pro_info = center_manage_getprobyid(setpro[i].proid)) == NULL){ continue; } - if(pro_it->second->cacheid != setpro[i].cacheid){ - continue; + + if(pro_info->cacheid == setpro[i].cacheid){ + info->pro_map.insert(std::pair<int,int>(pro_info->proid,pro_info->cacheid)); } + center_manage_putpro(pro_info); - info->pro_map.insert(std::pair<int,center_pro_info*>(pro_it->second->proid,pro_it->second)); }else if(setpro[i].type == 1){ info->pro_map.erase(setpro[i].proid); } } - judge_submit_waitqueue(); + judge_run_waitqueue(); delete setpro; } void judge_conn::recv_reqpro(void *buf,size_t len,void *data){ @@ -338,29 +353,37 @@ void judge_conn::recv_reqpro(void *buf,size_t len,void *data){ center_com_sendpro *sendpro; reqpro = (center_com_reqpro*)buf; - if((pro_it = center_manage_promap.find(reqpro->proid)) == center_manage_promap.end()){ - //fix - }else{ - pro_info = pro_it->second; - - snprintf(tpath,sizeof(tpath),"tmp/propack/%d.tar.bz2",pro_info->proid); + try{ + if((pro_info = center_manage_getprobyid(reqpro->proid)) == NULL){ + throw -1; + } + if(pro_info->cacheid != reqpro->cacheid){ + throw -1; + } + + snprintf(tpath,sizeof(tpath),"tmp/propack/%d_%d.tar.bz2",pro_info->proid,pro_info->cacheid); fd = open(tpath,O_RDONLY); - if(fstat(fd,&st)){ - //fix - }else{ - write_buf = create_combuf(CENTER_COMCODE_SENDPRO,sizeof(center_com_sendpro),write_len,(void**)&sendpro); - sendpro->proid = pro_info->proid; - sendpro->cacheid = pro_info->cacheid; - sendpro->filesize = st.st_size; - printf("sendpro:%lu\n",sendpro->filesize); + fstat(fd,&st); + write_buf = create_combuf(CENTER_COMCODE_SENDPRO,sizeof(center_com_sendpro),write_len,(void**)&sendpro); + sendpro->proid = pro_info->proid; + sendpro->cacheid = pro_info->cacheid; + sendpro->filesize = st.st_size; + printf("sendpro:%lu\n",sendpro->filesize); - writebytes(write_buf,write_len,NULL,NULL); - writefile(fd,st.st_size,NULL,NULL); + writebytes(write_buf,write_len,NULL,NULL); + writefile(fd,st.st_size,done_sendpro_fn,pro_info); + }catch(int err){ + if(pro_info != NULL){ + center_manage_putpro(pro_info); } } delete reqpro; } +void judge_conn::done_sendpro(void *buf,size_t len,void *data){ + close((int)((long)buf)); + center_manage_putpro((center_pro_info*)data); +} void judge_conn::recv_setjmod(void *buf,size_t len,void *data){ int i; int count; @@ -385,7 +408,7 @@ void judge_conn::recv_setjmod(void *buf,size_t len,void *data){ } } - judge_submit_waitqueue(); + judge_run_waitqueue(); delete setjmod; } void judge_conn::recv_reqjmod(void *buf,size_t len,void *data){ @@ -456,7 +479,7 @@ void judge_conn::recv_reqcode(void *buf,size_t len,void *data){ } -static int judge_submit_waitqueue(){ +static int judge_run_waitqueue(){ int count; judge_submit_info *sub_info; bool wait_flag; @@ -519,6 +542,18 @@ int center_judge_dispatch(int evflag,void *data){ } int center_judge_submit(int subid,int proid,int lang,char *set_data,size_t set_len){ judge_submitqueue.push(new judge_submit_info(subid,proid,lang,set_data,set_len)); - judge_submit_waitqueue(); + judge_run_waitqueue(); + return 0; +} +int center_judge_updatepro(std::vector<std::pair<int,int> > &pro_list){ + int i; + int j; + std::list<judge_info*>::iterator judge_it; + judge_info *info; + + for(judge_it = judge_runlist.begin();judge_it != judge_runlist.end();judge_it++){ + (*judge_it)->updatepro(pro_list); + } + return 0; } diff --git a/toj/center/src/center_judge.h b/toj/center/src/center_judge.h index 74b2daf..99a3cf9 100644..100755 --- a/toj/center/src/center_judge.h +++ b/toj/center/src/center_judge.h @@ -12,7 +12,7 @@ public: judge_conn *conn_main; std::list<judge_conn*> conn_list; std::list<judge_info*>::iterator judge_it; - std::map<int,center_pro_info*> pro_map; + std::map<int,int> pro_map; std::map<std::string,center_jmod_info*> jmod_map; judge_info(); @@ -21,6 +21,7 @@ public: int setinfo(int avail); int submit(judge_submit_info *submit_info); int result(int subid,char *res_data); + int updatepro(std::vector<std::pair<int,int> > &pro_list); }; class judge_conn : public netio{ @@ -31,6 +32,7 @@ private: netio_iofn<judge_conn> *recv_result_fn; netio_iofn<judge_conn> *recv_setpro_fn; netio_iofn<judge_conn> *recv_reqpro_fn; + netio_iofn<judge_conn> *done_sendpro_fn; netio_iofn<judge_conn> *recv_setjmod_fn; netio_iofn<judge_conn> *recv_reqjmod_fn; netio_iofn<judge_conn> *recv_reqcode_fn; @@ -42,6 +44,7 @@ private: void recv_result(void *buf,size_t len,void *data); void recv_setpro(void *buf,size_t len,void *data); void recv_reqpro(void *buf,size_t len,void *data); + void done_sendpro(void *buf,size_t len,void *data); void recv_setjmod(void *buf,size_t len,void *data); void recv_reqjmod(void *buf,size_t len,void *data); void recv_reqcode(void *buf,size_t len,void *data); @@ -54,7 +57,7 @@ public: ~judge_conn(); int send_setid(int judgeid); int send_submit(judge_submit_info* submit_info); - int send_setpro(int *proid,int *cacheid,int type,int count); + int send_setpro(std::vector<std::pair<int,int> > &pro_list,int type); int send_setjmod(char **jmod_name,int *cacheid,int type,int count); virtual int readidle(); }; @@ -64,23 +67,23 @@ public: int subid; int proid; int lang; - char set_data[JUDGE_SET_DATAMAX]; + char *set_data; size_t set_len; judge_submit_info(int subid,int proid,int lang,char *setdata,size_t setlen){ this->subid = subid; this->proid = proid; this->lang = lang; - if(setlen > JUDGE_SET_DATAMAX){ - memcpy(this->set_data,setdata,JUDGE_SET_DATAMAX); - }else{ - memcpy(this->set_data,setdata,setlen); - } + this->set_data = new char[setlen]; + memcpy(this->set_data,setdata,setlen); this->set_len = setlen; } + ~judge_submit_info(){ + delete this->set_data; + } }; -static int judge_submit_waitqueue(); +static int judge_run_waitqueue(); static std::map<int,judge_info*> judge_idmap; static std::list<judge_info*> judge_runlist; @@ -90,17 +93,12 @@ int center_judge_init(); void* center_judge_addconn(int fd); int center_judge_dispatch(int evflag,void *data); int center_judge_submit(int subid,int proid,int lang,char *setdata,size_t setlen); +int center_judge_updatepro(std::vector<std::pair<int,int> > &pro_list); extern int center_manage_result(int subid,char *res_data); +extern center_pro_info* center_manage_getprobyid(int proid); +extern int center_manage_getpro(center_pro_info *pro_info); +extern int center_manage_putpro(center_pro_info *pro_info); extern std::map<std::string,center_jmod_info*> center_manage_jmodmap; extern std::map<int,center_pro_info*> center_manage_promap; - - - -/*#define JUDGE_DB_MAXSCOREMAX 1024 -static int tmp_init(); -static int tmp_update(int submitid,int count,void *data); -static int server_updatedb(PGconn *sqlc,int submitid,int result_count,struct judgx_line_result *result); - -static PGconn *tmp_sqlc;*/ diff --git a/toj/center/src/center_manage.cpp b/toj/center/src/center_manage.cpp index 1155ab0..454faf2 100644..100755 --- a/toj/center/src/center_manage.cpp +++ b/toj/center/src/center_manage.cpp @@ -8,6 +8,7 @@ #include<semaphore.h> #include<libpq-fe.h> #include<sys/eventfd.h> +#include<sys/stat.h> #include<json/json.h> #include<vector> #include<queue> @@ -16,20 +17,26 @@ #include"tpool.h" #include"/srv/http/toj/php/event_exec.h" -#include"center.h" #include"judge_def.h" #include"judgm_manage.h" +#include"center.h" #include"center_manage.h" int center_manage_init(tpool **tpinfo){ - manage_packtp = new tpool(4); - manage_packtp->start(); - *tpinfo = manage_packtp; - - manage_packcode_thfn = new tpool_static_fn(manage_packcode_th); - manage_packcode_cbfn = new tpool_static_fn(manage_packcode_cb); - + manage_tp = new tpool(4); + manage_tp->start(); + *tpinfo = manage_tp; + + manage_updatepro_thfn = new tpool_static_fn(manage_updatepro_th); + manage_updatepro_cbfn = new tpool_static_fn(manage_updatepro_cb); + manage_updatejmod_thfn = new tpool_static_fn(manage_updatejmod_th); + manage_updatejmod_cbfn = new tpool_static_fn(manage_updatejmod_cb); + manage_submit_thfn = new tpool_static_fn(manage_submit_th); + manage_submit_cbfn = new tpool_static_fn(manage_submit_cb); + + //run when startup center_manage_updatedata(); + center_manage_submitwait(); return 0; } PGconn* center_manage_conndb(){ @@ -45,12 +52,15 @@ int center_manage_updatedata(){ PGconn *db_conn; PGresult *db_res; int db_count; + int cacheid; center_jmod_info *jmod_info; int proid; int lang_flag; std::map<std::string,center_jmod_info*>::iterator jmod_it; center_pro_info *pro_info; + std::vector<std::pair<int,int> > pro_list; + if((db_conn = center_manage_conndb()) == NULL){ return -1; } @@ -66,10 +76,9 @@ int center_manage_updatedata(){ jmod_info = new center_jmod_info(PQgetvalue(db_res,i,0),2); center_manage_jmodmap.insert(std::pair<std::string,center_jmod_info*>(jmod_info->name,jmod_info)); } - PQclear(db_res); - db_res = PQexec(db_conn,"SELECT \"proid\",\"jmodname\",\"lang\" FROM \"problem\" INNER JOIN \"mod\" ON (\"problem\".\"modid\"=\"mod\".\"modid\");"); + db_res = PQexec(db_conn,"SELECT \"proid\",\"cacheid\",\"lang\",\"jmodname\" FROM \"problem\" INNER JOIN \"mod\" ON (\"problem\".\"modid\"=\"mod\".\"modid\");"); if(PQresultStatus(db_res) != PGRES_TUPLES_OK){ center_manage_closedb(db_conn); return -1; @@ -78,18 +87,57 @@ int center_manage_updatedata(){ db_count = PQntuples(db_res); for(i = 0;i < db_count;i++){ sscanf(PQgetvalue(db_res,i,0),"%d",&proid); + sscanf(PQgetvalue(db_res,i,1),"%d",&cacheid); sscanf(PQgetvalue(db_res,i,2),"%d",&lang_flag); - if((jmod_it = center_manage_jmodmap.find(PQgetvalue(db_res,i,1))) == center_manage_jmodmap.end()){ + if((jmod_it = center_manage_jmodmap.find(PQgetvalue(db_res,i,3))) == center_manage_jmodmap.end()){ continue; } - pro_info = new center_pro_info(proid,1,jmod_it->second,lang_flag); - center_manage_promap.insert(std::pair<int,center_pro_info*>(pro_info->proid,pro_info)); + + if(manage_updatepro(proid,cacheid,jmod_it->second,lang_flag) == 1){ + pro_list.push_back(std::make_pair(proid,cacheid)); + + printf("pro update %d %d\n",proid,cacheid); + } + } + PQclear(db_res); + + if(!pro_list.empty()){ + center_judge_updatepro(pro_list); + } + + center_manage_closedb(db_conn); + return 0; +} +int center_manage_submitwait(){ + int i; + + PGconn *db_conn; + PGresult *db_res; + int db_count; + int subid; + + if((db_conn = center_manage_conndb()) == NULL){ + return -1; + } + + db_res = PQexec(db_conn,"SELECT \"subid\" FROM \"submit\" WHERE \"result\"=100;"); + if(PQresultStatus(db_res) != PGRES_TUPLES_OK){ + center_manage_closedb(db_conn); + return -1; + } + + db_count = PQntuples(db_res); + for(i = 0;i < db_count;i++){ + sscanf(PQgetvalue(db_res,i,0),"%d",&subid); + center_manage_submit(subid,"{}"); } PQclear(db_res); center_manage_closedb(db_conn); return 0; } + + int center_manage_submit(int subid,char *param){ PGconn *db_conn; PGresult *db_res; @@ -104,7 +152,7 @@ int center_manage_submit(int subid,char *param){ std::map<int,center_pro_info*>::iterator pro_it; center_pro_info *pro_info; center_jmod_info *jmod_info; - center_submit_info *sub_info; + manage_submit_info *sub_info; if((db_conn = center_manage_conndb()) == NULL){ return -1; @@ -148,39 +196,39 @@ int center_manage_submit(int subid,char *param){ rejudge_flag = true; } - sub_info = new center_submit_info(subid,uid,jmod_info,pro_info,lang,rejudge_flag,param); - center_manage_submap.insert(std::pair<int,center_submit_info*>(sub_info->subid,sub_info)); - manage_packtp->add(manage_packcode_thfn,sub_info,manage_packcode_cbfn,sub_info); + center_manage_getpro(pro_info); + + sub_info = new manage_submit_info(subid,uid,jmod_info,pro_info,lang,rejudge_flag,param); + manage_submap.insert(std::pair<int,manage_submit_info*>(sub_info->subid,sub_info)); + manage_tp->add(manage_submit_thfn,sub_info,manage_submit_cbfn,sub_info); return 0; } -static void manage_packcode_th(void *data){ - center_submit_info *sub_info; - int subid; +static void manage_submit_th(void *data){ + manage_submit_info *sub_info; char dir_path[PATH_MAX + 1]; char pack_path[PATH_MAX + 1]; - sub_info = (center_submit_info*)data; - subid = sub_info->subid; + sub_info = (manage_submit_info*)data; - snprintf(dir_path,sizeof(dir_path),"submit/%d/%d/data",(subid / 1000) * 1000,subid); - snprintf(pack_path,sizeof(pack_path),"tmp/codepack/%d.tar.bz2",subid); - pack_pack(pack_path,dir_path); + snprintf(dir_path,sizeof(dir_path),"submit/%d/%d/data",(sub_info->subid / 1000) * 1000,sub_info->subid); + snprintf(pack_path,sizeof(pack_path),"tmp/codepack/%d.tar.bz2",sub_info->subid); + tool_pack(pack_path,dir_path); } -static void manage_packcode_cb(void *data){ - center_submit_info *sub_info; +static void manage_submit_cb(void *data){ + manage_submit_info *sub_info; center_jmod_info *jmod_info; center_pro_info *pro_info; char cwd_path[PATH_MAX + 1]; char tpath[PATH_MAX + 1]; - judgm_manage_submit_fn mod_sub_fn; - judgm_manage_submitinfo mod_sub_info; + judgm_manage_info *mg_info; + judgm_manage_submit_fn mg_sub_fn; FILE *set_file; char lchr; char tchr; - sub_info = (center_submit_info*)data; + sub_info = (manage_submit_info*)data; jmod_info = sub_info->jmod_info; pro_info = sub_info->pro_info; @@ -192,15 +240,12 @@ static void manage_packcode_cb(void *data){ jmod_info->manage_sub_fn = dlsym(jmod_info->manage_dll,"submit"); jmod_info->manage_res_fn = dlsym(jmod_info->manage_dll,"result"); } - mod_sub_fn = (judgm_manage_submit_fn)jmod_info->manage_sub_fn; - - mod_sub_info.uid = sub_info->uid; - mod_sub_info.subid = sub_info->subid; - mod_sub_info.proid = pro_info->proid; - mod_sub_info.lang = sub_info->lang; - mod_sub_info.param = sub_info->param; - snprintf(mod_sub_info.pro_path,sizeof(mod_sub_info.pro_path),"pro/%d",pro_info->proid); - + mg_sub_fn = (judgm_manage_submit_fn)jmod_info->manage_sub_fn; + + mg_info = sub_info->manage_info; + snprintf(mg_info->pro_path,sizeof(mg_info->pro_path),"pro/%d",pro_info->proid); + snprintf(mg_info->res_path,sizeof(mg_info->res_path),"submit/%d/%d/result",(sub_info->subid / 1000) * 1000,sub_info->subid); + snprintf(tpath,sizeof(tpath),"pro/%d/setting",pro_info->proid); set_file = fopen(tpath,"r"); lchr = '\n'; @@ -211,47 +256,24 @@ static void manage_packcode_cb(void *data){ } lchr = tchr; } - mod_sub_info.set_file = set_file; - mod_sub_fn(&mod_sub_info,&sub_info->jmod_manage_data); + mg_sub_fn(mg_info,set_file); fclose(set_file); } -static int manage_notice(int subid,int uid,int proid,int result,double score,int runtime,int memory,bool rejudge_flag){ - char msg[4096]; - json_object *jso_msg; - json_object *jso_arg; - - jso_msg = json_object_new_object(); - json_object_object_add(jso_msg,"type",json_object_new_string("result")); - json_object_object_add(jso_msg,"subid",json_object_new_int(subid)); - json_object_object_add(jso_msg,"proid",json_object_new_int(proid)); - json_object_object_add(jso_msg,"result",json_object_new_int(result)); - json_object_object_add(jso_msg,"score",json_object_new_double(score)); - json_object_object_add(jso_msg,"runtime",json_object_new_int(runtime)); - json_object_object_add(jso_msg,"memory",json_object_new_int(memory / 1024UL)); - json_object_object_add(jso_msg,"rejudge_flag",json_object_new_boolean(rejudge_flag)); - - jso_arg = json_object_new_array(); - json_object_array_add(jso_arg,json_object_new_int(uid)); - json_object_array_add(jso_arg,jso_msg); - - event_exec("pzreadtest.php","center_result_event",json_object_get_string(jso_arg)); - json_object_put(jso_arg); - +DLL_PUBLIC int center_manage_queuesubmit(int subid,int proid,int lang,char *set_data,size_t set_len){ + center_judge_submit(subid,proid,lang,set_data,set_len); return 0; } int center_manage_result(int subid,char *res_data){ - int ret; - - std::map<int,center_submit_info*>::iterator sub_it; - center_submit_info *sub_info; + std::map<int,manage_submit_info*>::iterator sub_it; + manage_submit_info *sub_info; center_jmod_info *jmod_info; char res_path[PATH_MAX + 1]; - judgm_manage_resultinfo res_info; - judgm_manage_result_fn res_fn; + judgm_manage_info *mg_info; + judgm_manage_result_fn mg_res_fn; PGconn *db_conn; PGresult *db_res; @@ -262,31 +284,25 @@ int center_manage_result(int subid,char *res_data){ char db_subid[32]; char *db_param[5]; - if((sub_it = center_manage_submap.find(subid)) == center_manage_submap.end()){ + if((sub_it = manage_submap.find(subid)) == manage_submap.end()){ return -1; } sub_info = sub_it->second; jmod_info = sub_info->jmod_info; + mg_info = sub_info->manage_info; - res_info.uid = sub_info->uid; - res_info.subid = subid; - res_info.proid = sub_info->pro_info->proid; - snprintf(res_path,sizeof(res_path),"submit/%d/%d/result",(subid / 1000) * 1000,subid); - res_info.res_path = res_path; - res_info.res_data = res_data; - res_fn = (judgm_manage_result_fn)jmod_info->manage_res_fn; - ret = res_fn(&res_info,sub_info->jmod_manage_data); - if(ret == 1){ - center_manage_submap.erase(sub_it); + mg_res_fn = (judgm_manage_result_fn)jmod_info->manage_res_fn; + if(mg_res_fn(mg_info,res_data)){ + manage_submap.erase(sub_it); if((db_conn = center_manage_conndb()) == NULL){ return -1; } - snprintf(db_result,sizeof(db_result),"%d",res_info.result); - snprintf(db_score,sizeof(db_score),"%lld",(int)res_info.score); - snprintf(db_runtime,sizeof(db_runtime),"%lu",res_info.runtime); - snprintf(db_memory,sizeof(db_memory),"%lu",res_info.memory / 1024UL); + snprintf(db_result,sizeof(db_result),"%d",mg_info->result); + snprintf(db_score,sizeof(db_score),"%lf",mg_info->score); + snprintf(db_runtime,sizeof(db_runtime),"%lu",mg_info->runtime); + snprintf(db_memory,sizeof(db_memory),"%lu",mg_info->memory / 1024UL); snprintf(db_subid,sizeof(db_subid),"%d",subid); db_param[0] = db_result; db_param[1] = db_score; @@ -307,12 +323,13 @@ int center_manage_result(int subid,char *res_data){ manage_notice(subid, sub_info->uid, sub_info->pro_info->proid, - res_info.result, - res_info.score, - res_info.runtime, - res_info.memory, + mg_info->result, + mg_info->score, + mg_info->runtime, + mg_info->memory, sub_info->rejudge_flag); + center_manage_putpro(sub_info->pro_info); delete sub_info; }else{ return -1; @@ -320,7 +337,279 @@ int center_manage_result(int subid,char *res_data){ return 0; } -DLL_PUBLIC int center_manage_queuesubmit(int subid,int proid,int lang,char *set_data,size_t set_len){ - center_judge_submit(subid,proid,lang,set_data,set_len); +static int manage_notice(int subid,int uid,int proid,int result,double score,int runtime,int memory,bool rejudge_flag){ + char msg[4096]; + json_object *jso_msg; + json_object *jso_arg; + + jso_msg = json_object_new_object(); + json_object_object_add(jso_msg,"type",json_object_new_string("result")); + json_object_object_add(jso_msg,"subid",json_object_new_int(subid)); + json_object_object_add(jso_msg,"proid",json_object_new_int(proid)); + json_object_object_add(jso_msg,"result",json_object_new_int(result)); + json_object_object_add(jso_msg,"score",json_object_new_double(score)); + json_object_object_add(jso_msg,"runtime",json_object_new_int(runtime)); + json_object_object_add(jso_msg,"memory",json_object_new_int(memory / 1024UL)); + json_object_object_add(jso_msg,"rejudge_flag",json_object_new_boolean(rejudge_flag)); + + jso_arg = json_object_new_array(); + json_object_array_add(jso_arg,json_object_new_int(uid)); + json_object_array_add(jso_arg,jso_msg); + + event_exec("pzreadtest.php","center_result_event",json_object_get_string(jso_arg)); + json_object_put(jso_arg); + + return 0; +} + + +center_pro_info* center_manage_getprobyid(int proid){ + std::map<int,center_pro_info*>::iterator pro_it; + center_pro_info *pro_info; + + if((pro_it = center_manage_promap.find(proid)) == center_manage_promap.end()){ + return NULL; + } + pro_info = pro_it->second; + + if(center_manage_getpro(pro_info)){ + return NULL; + } + + return pro_info; +} +int center_manage_getpro(center_pro_info *pro_info){ + pro_info->ref_count++; + return 0; +} +int center_manage_putpro(center_pro_info *pro_info){ + char tpath[PATH_MAX + 1]; + + pro_info->ref_count--; + if(pro_info->ref_count == 0){ + snprintf(tpath,sizeof(tpath),"tmp/pro/%d_%d",pro_info->proid,pro_info->cacheid); + tool_cleardir(tpath); + rmdir(tpath); + + snprintf(tpath,sizeof(tpath),"tmp/propack/%d_%d.tar.bz2",pro_info->proid,pro_info->cacheid); + unlink(tpath); + + delete pro_info; + } + return 0; +} +static int manage_updatepro(int proid,int cacheid,center_jmod_info *jmod_info,int lang_flag){ + std::map<int,center_pro_info*>::iterator pro_it; + center_pro_info *old_pro_info; + center_pro_info *update_pro_info; + + char tpath[PATH_MAX + 1]; + struct stat st; + std::pair<std::map<int,center_pro_info*>::iterator,bool> ins_ret; + + if((pro_it = center_manage_promap.find(proid)) == center_manage_promap.end()){ + old_pro_info = NULL; + }else{ + old_pro_info = pro_it->second; + + if(old_pro_info->state == CENTER_CACHESTATE_READY && cacheid == old_pro_info->cacheid){ + return 1; + } + if(old_pro_info->state == CENTER_CACHESTATE_UPDATE && (cacheid <= old_pro_info->cacheid || cacheid <= old_pro_info->update_cacheid)){ + return -1; + } + + old_pro_info->state = CENTER_CACHESTATE_UPDATE; + old_pro_info->update_cacheid = cacheid; + } + + update_pro_info = new center_pro_info(proid,cacheid,jmod_info,lang_flag); //set cacheid 0 to new pro + center_manage_getpro(update_pro_info); + + snprintf(tpath,sizeof(tpath),"tmp/pro/%d_%d",update_pro_info->proid,update_pro_info->cacheid); + if(!stat(tpath,&st)){ + snprintf(tpath,sizeof(tpath),"tmp/propack/%d_%d.tar.bz2",update_pro_info->proid,update_pro_info->cacheid); + if(!stat(tpath,&st)){ + + if(old_pro_info != NULL){ + center_manage_putpro(old_pro_info); + } + + ins_ret = center_manage_promap.insert(std::make_pair(update_pro_info->proid,update_pro_info)); + if(ins_ret.second == false){ + ins_ret.first->second = update_pro_info; + } + + return 1; + } + } + + manage_tp->add(manage_updatepro_thfn,update_pro_info,manage_updatepro_cbfn,update_pro_info); + return 0; } +static void manage_updatepro_th(void *data){ + center_pro_info *pro_info; + char src_path[PATH_MAX + 1]; + char dir_path[PATH_MAX + 1]; + char pack_path[PATH_MAX + 1]; + + pro_info = (center_pro_info*)data; + + snprintf(src_path,sizeof(src_path),"pro/%d",pro_info->proid); + snprintf(dir_path,sizeof(dir_path),"tmp/pro/%d_%d",pro_info->proid,pro_info->cacheid); + tool_copydir(src_path,dir_path); + + snprintf(pack_path,sizeof(pack_path),"tmp/propack/%d_%d.tar.bz2",pro_info->proid,pro_info->cacheid); + tool_pack(pack_path,dir_path); +} +static void manage_updatepro_cb(void *data){ + center_pro_info *old_pro_info; + center_pro_info *update_pro_info; + std::pair<std::map<int,center_pro_info*>::iterator,bool> ins_ret; + std::vector<std::pair<int,int> > pro_pair; + + update_pro_info = (center_pro_info*)data; + + ins_ret = center_manage_promap.insert(std::make_pair(update_pro_info->proid,update_pro_info)); + if(ins_ret.second == false){ + old_pro_info = ins_ret.first->second; + + if(update_pro_info->cacheid <= old_pro_info->cacheid){ + center_manage_putpro(update_pro_info); + return; + } + + center_manage_putpro(ins_ret.first->second); + ins_ret.first->second = update_pro_info; + } + + pro_pair.push_back(std::make_pair(update_pro_info->proid,update_pro_info->cacheid)); + center_judge_updatepro(pro_pair); +} + +center_jmod_info* center_manage_getjmodbyname(char *name){ + std::map<std::string,center_jmod_info*>::iterator jmod_it; + center_jmod_info *jmod_info; + + if((jmod_it = center_manage_jmodmap.find(name)) == center_manage_jmodmap.end()){ + return NULL; + } + jmod_info = jmod_it->second; + + if(center_manage_getjmod(jmod_info)){ + return NULL; + } + + return jmod_info; +} +int center_manage_getjmod(center_jmod_info *jmod_info){ + jmod_info->ref_count++; + return 0; +} +int center_manage_putjmod(center_jmod_info *jmod_info){ + char tpath[PATH_MAX + 1]; + + jmod_info->ref_count--; + if(jmod_info->ref_count == 0){ + snprintf(tpath,sizeof(tpath),"tmp/jmod/%s_%d",jmod_info->name,jmod_info->cacheid); + tool_cleardir(tpath); + rmdir(tpath); + + snprintf(tpath,sizeof(tpath),"tmp/jmodpack/%s_%d.tar.bz2",jmod_info->name,jmod_info->cacheid); + unlink(tpath); + + delete jmod_info; + } + return 0; +} +static int manage_updatejmod(char *name,int cacheid){ + std::map<std::string,center_jmod_info*>::iterator jmod_it; + center_jmod_info *old_jmod_info; + center_jmod_info *update_jmod_info; + + char tpath[PATH_MAX + 1]; + struct stat st; + std::pair<std::map<std::string,center_jmod_info*>::iterator,bool> ins_ret; + + if((jmod_it = center_manage_jmodmap.find(name)) == center_manage_jmodmap.end()){ + old_jmod_info = NULL; + }else{ + old_jmod_info = jmod_it->second; + + if(old_jmod_info->state == CENTER_CACHESTATE_READY && cacheid == old_jmod_info->cacheid){ + return -1; + } + if(old_jmod_info->state == CENTER_CACHESTATE_UPDATE && (cacheid <= old_jmod_info->cacheid || cacheid <= old_jmod_info->update_cacheid)){ + return -1; + } + + old_jmod_info->state = CENTER_CACHESTATE_UPDATE; + old_jmod_info->update_cacheid = cacheid; + } + + update_jmod_info = new center_jmod_info(name,cacheid); + center_manage_getjmod(update_jmod_info); + + snprintf(tpath,sizeof(tpath),"tmp/jmod/%s_%d",update_jmod_info->name,update_jmod_info->cacheid); + if(!stat(tpath,&st)){ + snprintf(tpath,sizeof(tpath),"tmp/jmodpack/%s_%d.tar.bz2",update_jmod_info->name,update_jmod_info->cacheid); + if(!stat(tpath,&st)){ + + if(old_jmod_info != NULL){ + center_manage_putjmod(old_jmod_info); + + ins_ret = center_manage_jmodmap.insert(std::make_pair(update_jmod_info->name,update_jmod_info)); + if(ins_ret.second == false){ + ins_ret.first->second = update_jmod_info; + } + + return 1; + } + } + } + + manage_tp->add(manage_updatejmod_thfn,update_jmod_info,manage_updatejmod_cbfn,update_jmod_info); + + return 0; +} +static void manage_updatejmod_th(void *data){ + center_jmod_info *jmod_info; + char src_path[PATH_MAX + 1]; + char dir_path[PATH_MAX + 1]; + char pack_path[PATH_MAX + 1]; + + jmod_info = (center_jmod_info*)data; + + snprintf(src_path,sizeof(src_path),"jmod/%s",jmod_info->name); + snprintf(dir_path,sizeof(dir_path),"tmp/jmod/%s_%d.tar.bz2",jmod_info->name,jmod_info->cacheid); + tool_copydir(src_path,dir_path); + + snprintf(pack_path,sizeof(pack_path),"tmp/jmodpack/%s_%d.tar.bz2",jmod_info->name,jmod_info->cacheid); + tool_pack(pack_path,dir_path); +} +static void manage_updatejmod_cb(void *data){ + center_jmod_info *old_jmod_info; + center_jmod_info *update_jmod_info; + std::pair<std::map<std::string,center_jmod_info*>::iterator,bool> ins_ret; + std::vector<std::pair<std::string,int> > jmod_pair; + + update_jmod_info = (center_jmod_info*)data; + + ins_ret = center_manage_jmodmap.insert(std::make_pair(update_jmod_info->name,update_jmod_info)); + if(ins_ret.second == false){ + old_jmod_info = ins_ret.first->second; + + if(update_jmod_info->cacheid <= old_jmod_info->cacheid){ + center_manage_putjmod(update_jmod_info); + } + + center_manage_putjmod(old_jmod_info); + ins_ret.first->second = update_jmod_info; + } + + jmod_pair.push_back(std::make_pair(update_jmod_info->name,update_jmod_info->cacheid)); + //wait + + // +} diff --git a/toj/center/src/center_manage.h b/toj/center/src/center_manage.h index 887ef77..1f84403 100644..100755 --- a/toj/center/src/center_manage.h +++ b/toj/center/src/center_manage.h @@ -1,23 +1,74 @@ -static void manage_packcode_th(void *data); -static void manage_packcode_cb(void *data); +class manage_submit_info{ +public: + int subid; + int uid; + center_jmod_info *jmod_info; + center_pro_info *pro_info; + int lang; + bool rejudge_flag; + char param[JUDGE_SUB_PARAMMAX]; + judgm_manage_info *manage_info; + + manage_submit_info(int subid,int uid,center_jmod_info *jmod_info,center_pro_info *pro_info,int lang,bool rejudge_flag,char *param){ + this->subid = subid; + this->uid = uid; + this->jmod_info = jmod_info; + this->pro_info = pro_info; + this->lang = lang; + this->rejudge_flag = rejudge_flag; + this->param[0] = '\0'; + strncat(this->param,param,sizeof(this->param)); + + this->manage_info = new judgm_manage_info(this->subid,this->uid,pro_info->proid,this->lang,this->param); + } + ~manage_submit_info(){ + delete this->manage_info; + } +}; + +static void manage_submit_th(void *data); +static void manage_submit_cb(void *data); static int manage_notice(int subid,int uid,int proid,int result,double score,int runtime,int memory,bool rejudge_flag); -static tpool *manage_packtp; -static tpool_static_fn *manage_packcode_thfn; -static tpool_static_fn *manage_packcode_cbfn; +static int manage_updatepro(int proid,int cacheid,center_jmod_info *jmod_info,int lang_flag); +static void manage_updatepro_th(void *data); +static void manage_updatepro_cb(void *data); +static int manage_updatejmod(char *name,int cacheid); +static void manage_updatejmod_th(void *data); +static void manage_updatejmod_cb(void *data); + +static tpool *manage_tp; +static tpool_static_fn *manage_updatepro_thfn; +static tpool_static_fn *manage_updatepro_cbfn; +static tpool_static_fn *manage_updatejmod_thfn; +static tpool_static_fn *manage_updatejmod_cbfn; +static tpool_static_fn *manage_submit_thfn; +static tpool_static_fn *manage_submit_cbfn; +static std::map<int,manage_submit_info*> manage_submap; int center_manage_init(tpool **tpinfo); PGconn* center_manage_conndb(); int center_manage_closedb(PGconn *conn); int center_manage_updatedata(); +int center_manage_submitwait(); int center_manage_submit(int subid,char *param); int center_manage_result(int subid,char *res_data); DLL_PUBLIC int center_manage_queuesubmit(int subid,int proid,int lang,char *set_data,size_t set_len); -std::map<std::string,center_jmod_info*> center_manage_jmodmap; +center_pro_info* center_manage_getprobyid(int proid); +int center_manage_getpro(center_pro_info*); +int center_manage_putpro(center_pro_info *pro_info); +center_jmod_info* center_manage_getjmodbyname(char *name); +int center_manage_getjmod(center_jmod_info *jmod_info); +int center_manage_putjmod(center_jmod_info *jmod_info); + std::map<int,center_pro_info*> center_manage_promap; -std::map<int,center_submit_info*> center_manage_submap; +std::map<std::string,center_jmod_info*> center_manage_jmodmap; + +extern int tool_pack(char *pack_path,char *dir_path); +extern int tool_unpack(char *pack_path,char *dir_path); +extern int tool_cleardir(char *path); +extern int tool_copydir(char *old_path,char *new_path); -extern int pack_pack(char *pack_path,char *dir_path); -extern int pack_unpack(char *pack_path,char *dir_path); extern int center_judge_submit(int subid,int proid,int lang,char *set_data,size_t set_len); +extern int center_judge_updatepro(std::vector<std::pair<int,int> > &pro_list); diff --git a/toj/center/src/center_server.cpp b/toj/center/src/center_server.cpp index a931822..030e273 100644..100755 --- a/toj/center/src/center_server.cpp +++ b/toj/center/src/center_server.cpp @@ -63,7 +63,14 @@ int server_web_conn::readio(){ param = buf + strlen(buf) + 1; printf("%d %s\n",subid,param); - center_manage_submit(subid,param); + //test + if(subid == -1){ + center_manage_updatedata(); + }else{ + center_manage_submit(subid,param); + } + + //test write(fd,"S",2); } @@ -112,13 +119,12 @@ int main(){ server_addepev(tpinfo->fd,EPOLLIN | EPOLLET,SERVER_EPEV_TPOOL,tpinfo); center_judge_init(); - judge_sfd = socket(AF_INET,SOCK_STREAM | SOCK_NONBLOCK,6); saddr.sin_family = AF_INET; saddr.sin_port = htons(SERVER_JUDGE_PORT); //saddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); //saddr.sin_addr.s_addr = htonl(INADDR_ANY); - saddr.sin_addr.s_addr = inet_addr("10.8.0.1"); + saddr.sin_addr.s_addr = inet_addr("10.8.0.2"); setsockopt(judge_sfd,SOL_SOCKET,SO_REUSEADDR,&saddr,sizeof(saddr)); bind(judge_sfd,(sockaddr*)&saddr,sizeof(saddr)); diff --git a/toj/center/src/center_server.h b/toj/center/src/center_server.h index 140a1d4..039e84b 100644..100755 --- a/toj/center/src/center_server.h +++ b/toj/center/src/center_server.h @@ -34,12 +34,12 @@ static int server_delepev(server_epevdata *epevdata); static int server_epfd; extern int center_manage_init(tpool **tpinfo); +extern int center_manage_updatedata(); extern int center_manage_submit(int subid,char *param); extern int center_judge_init(); extern void* center_judge_addconn(int fd); extern int center_judge_dispatch(int ev_flag,void *data); -extern int center_judge_submit(int subid,int proid); extern int pack_pack(char *pack_path,char *dir_path); extern int pack_unpack(char *pack_path,char *target_path); diff --git a/toj/center/src/hyperio/Makefile b/toj/center/src/hyperio/Makefile new file mode 100755 index 0000000..655e473 --- /dev/null +++ b/toj/center/src/hyperio/Makefile @@ -0,0 +1,13 @@ +ifneq ($(KERNELRELEASE),) + hyperio-objs := hyperio_mod.o judgk_hyperio.o + obj-m := hyperio.o +else + KERNEL_SOURCE := /usr/lib/modules/$(shell uname -r)/build + PWD := $(shell pwd) +default: + ${MAKE} -C ${KERNEL_SOURCE} SUBDIRS=${PWD} modules + + g++ -O2 test.cpp -o test +clean: + ${MAKE} -C ${KERNEL_SOURCE} SUBDIRS=${PWD} clean +endif diff --git a/toj/center/src/hyperio/hyperio_mod.c b/toj/center/src/hyperio/hyperio_mod.c new file mode 100755 index 0000000..a188b14 --- /dev/null +++ b/toj/center/src/hyperio/hyperio_mod.c @@ -0,0 +1,58 @@ +#include<linux/module.h> +#include<linux/kernel.h> +#include<linux/kdev_t.h> +#include<linux/device.h> +#include<linux/cdev.h> +#include<linux/fs.h> + +#include"../judgk.h" +#include"../judgk_com.h" +#include"hyperio_mod.h" + +static int __init mod_init(){ + alloc_chrdev_region(&mod_dev,0,1,"hyperio"); + mod_class = class_create(THIS_MODULE,"chardev"); + device_create(mod_class,NULL,mod_dev,NULL,"hyperio"); + cdev_init(&mod_cdev,&mod_fops); + cdev_add(&mod_cdev,mod_dev,1); + + judgk_hyperio_init(); + + pr_alert("hyperio:Init\n"); + return 0; +} +static void __exit mod_exit(){ + judgk_hyperio_exit(); + + cdev_del(&mod_cdev); + device_destroy(mod_class,mod_dev); + class_destroy(mod_class); + unregister_chrdev_region(mod_dev,1); + + pr_alert("hyperio:Exit\n"); +} +module_init(mod_init); +module_exit(mod_exit); +MODULE_LICENSE("Dual BSD/GPL"); + +static long mod_ioctl(struct file *filp,unsigned int cmd,unsigned long arg){ + long ret; + + ret = 0; + switch(cmd){ + case IOCTL_HYPERIO_ADD: + ret = judgk_hyperio_add(filp); + break; + case IOCTL_HYPERIO_READ: + ret = judgk_hyperio_read(filp,arg); + break; + case IOCTL_HYPERIO_WRITE: + ret = judgk_hyperio_write(filp,arg); + break; + case IOCTL_HYPERIO_DEL: + ret = judgk_hyperio_del(filp); + break; + } + + return ret; +} diff --git a/toj/center/src/hyperio/hyperio_mod.h b/toj/center/src/hyperio/hyperio_mod.h new file mode 100755 index 0000000..3d75b68 --- /dev/null +++ b/toj/center/src/hyperio/hyperio_mod.h @@ -0,0 +1,21 @@ +static int __init mod_init(void); +static void __exit mod_exit(void); + +static long mod_ioctl(struct file *filp,unsigned int cmd,unsigned long arg); + +static dev_t mod_dev; +static struct cdev mod_cdev; +static struct class *mod_class; +extern int judgk_hyperio_mmap(struct file *filp,struct vm_area_struct *vma); +static struct file_operations mod_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = mod_ioctl, + .mmap = judgk_hyperio_mmap +}; + +extern int judgk_hyperio_init(void); +extern int judgk_hyperio_exit(void); +extern int judgk_hyperio_add(struct file *filp); +extern int judgk_hyperio_read(struct file *filp,size_t len); +extern int judgk_hyperio_write(struct file *filp,size_t len); +extern int judgk_hyperio_del(struct file *filp); diff --git a/toj/center/src/hyperio/test.cpp b/toj/center/src/hyperio/test.cpp new file mode 100755 index 0000000..18e536b --- /dev/null +++ b/toj/center/src/hyperio/test.cpp @@ -0,0 +1,173 @@ +#include<stdio.h> +#include<stdlib.h> +#include<string.h> +#include<unistd.h> +#include<fcntl.h> +#include<time.h> +#include<limits.h> +#include<math.h> +#include<termios.h> +#include<sys/ioctl.h> +#include<sys/types.h> +#include<sys/mman.h> +#include<sys/wait.h> + +#include"../judge_def.h" +#include"../judgm_lib.h" + +int fd; +/*char *rbuf; +off_t roff = 0; + +int judgm_hyperio_compare(char *buf,size_t len){ + int flag; + size_t remain; + off_t off; + size_t data_len; + size_t cmp_len; + + flag = 0; + remain = len; + off = 0; + data_len = 0; + cmp_len = 0; + while(remain > 0 && flag == 0){ + if(data_len == 0){ + if((data_len = ioctl(fd,IOCTL_READ,cmp_len)) <= 0){ + return -1; + } + } + if(remain < data_len){ + cmp_len = remain; + }else{ + cmp_len = data_len; + } + + if((roff + cmp_len) < BUF_SIZE){ + flag |= memcmp(rbuf + roff,buf + off,cmp_len); + roff += cmp_len; + }else{ + flag |= memcmp(rbuf + roff,buf + off,BUF_SIZE - roff); + flag |= memcmp(rbuf,buf + off + (BUF_SIZE - roff),(cmp_len + roff) - BUF_SIZE); + roff = (cmp_len + roff) - BUF_SIZE; + } + remain -= cmp_len; + off += cmp_len; + } + if(cmp_len > 0){ + ioctl(fd,IOCTL_READ,-(long)cmp_len); + } + + if(flag == 0){ + return 0; + }else{ + return -1; + } +}*/ + +int main(){ + int i,j; + char *buf; + int idx; + int pid; + char str[4096]; + int a,b; + int l; + + judgm_hyperio *hyperio; + + fd = open("/dev/judgk",O_RDWR); + hyperio = new judgm_hyperio(fd); + + printf("%d\n",hyperio->tty_idx); + + if((pid = fork()) == 0){ + int outfd; + + outfd = judgm_hyperio::get_ttyfd(0); + + //dup2(fd,0); + dup2(outfd,1); + + printf("Hello World\n"); + char *argv[] = {NULL,NULL}; + char *envp[] = {NULL}; + + execve("/srv/http/toj/center/judge/tmp/run/1/test",argv,envp); + exit(0); + } + + printf("%d\n",hyperio->compare("Hello World\n",12)); + + waitpid(pid,NULL,0); + + getchar(); + delete hyperio; + close(fd); + + /*flag = 0; + roff = 0; + woff = 0; + srand(23); + for(i = 0;i < 1000000;i++){ + a = rand() % 65536; + b = rand() % 65536; + + snprintf(str,sizeof(str),"%d %d\n",a,b); + l = strlen(str); + j = l; + len = 0; + while(j > 0){ + len = ioctl(fd,IOCTL_WRITE,len); + if(j < len){ + len = j; + } + + if((len + woff) < BUF_SIZE){ + memcpy(wbuf + woff,str + (l - j),len); + woff += len; + }else{ + memcpy(wbuf + woff,str + (l - j),BUF_SIZE - woff); + memcpy(wbuf,str + (l - j) + (BUF_SIZE - woff),(len + woff) - BUF_SIZE); + woff = (len + woff) - BUF_SIZE; + } + + j -= len; + } + ioctl(fd,IOCTL_WRITE,-len); + + snprintf(str,sizeof(str),"%d\n",a + b); + l = strlen(str); + j = l; + len = 0; + while(j > 0){ + len = ioctl(fd,IOCTL_READ,len); + if(len <= 0){ + flag = 1; + break; + } + if(j < len){ + len = j; + } + + if((roff + len) < BUF_SIZE){ + flag |= memcmp(rbuf + roff,str + (l - j),len); + roff += len; + }else{ + flag |= memcmp(rbuf + roff,str + (l - j),BUF_SIZE - roff); + flag |= memcmp(rbuf,str + (l - j) + (BUF_SIZE - roff),(len + roff) - BUF_SIZE); + roff = (len + roff) - BUF_SIZE; + } + + j -= len; + } + ioctl(fd,IOCTL_READ,-len); + + if(flag != 0){ + printf("WA\n"); + break; + } + }*/ + + return 0; +} diff --git a/toj/center/src/jmod_test.h b/toj/center/src/jmod_test.h index 94cc23d..844f5c8 100644..100755 --- a/toj/center/src/jmod_test.h +++ b/toj/center/src/jmod_test.h @@ -5,10 +5,10 @@ typedef int (*check_run_fn)(int &status,char *err_msg); typedef int (*check_stop_fn)(); struct line_set_data{ - int test_id; + int id; }; struct line_result_data{ - int test_id; + int id; int status; double score; unsigned long runtime; diff --git a/toj/center/src/jmod_test_check.cpp b/toj/center/src/jmod_test_check.cpp index ae4d060..ae4d060 100644..100755 --- a/toj/center/src/jmod_test_check.cpp +++ b/toj/center/src/jmod_test_check.cpp diff --git a/toj/center/src/jmod_test_check.h b/toj/center/src/jmod_test_check.h index 20a6286..20a6286 100644..100755 --- a/toj/center/src/jmod_test_check.h +++ b/toj/center/src/jmod_test_check.h diff --git a/toj/center/src/jmod_test_line.cpp b/toj/center/src/jmod_test_line.cpp index bd855c8..be1177c 100644..100755 --- a/toj/center/src/jmod_test_line.cpp +++ b/toj/center/src/jmod_test_line.cpp @@ -11,7 +11,7 @@ #include"jmod_test.h" #include"jmod_test_line.h" -static int line_load_setfile(FILE *set_file,int test_id,int &timelimit,int &memlimit,double &score){ +static int line_load_setfile(FILE *set_file,int id,int &timelimit,int &memlimit,double &score){ int ret; json_object *jso; @@ -22,7 +22,7 @@ static int line_load_setfile(FILE *set_file,int test_id,int &timelimit,int &meml timelimit = json_object_get_int(json_object_object_get(jso,"timelimit")); memlimit = json_object_get_int(json_object_object_get(jso,"memlimit")); - score = json_object_get_double(json_object_array_get_idx(json_object_object_get(jso,"score"),test_id - 1)); + score = json_object_get_double(json_object_array_get_idx(json_object_object_get(jso,"score"),id - 1)); json_object_put(jso); return 0; @@ -118,14 +118,14 @@ DLL_PUBLIC int run(judgm_line_info *info){ res_data = (line_result_data*)info->res_data; info->res_len = sizeof(line_result_data); - res_data->test_id = set_data->test_id; + res_data->id = set_data->id; res_data->status = JUDGE_ERR; res_data->score = 0; res_data->runtime = 0; res_data->memory = 0; res_data->err_msg[0] = '\0'; - if(line_load_setfile(info->set_file,set_data->test_id,set_timelimit,set_memlimit,set_score)){ + if(line_load_setfile(info->set_file,set_data->id,set_timelimit,set_memlimit,set_score)){ return -1; } @@ -142,7 +142,7 @@ DLL_PUBLIC int run(judgm_line_info *info){ line_chk_stop_fn = (check_stop_fn)dlsym(info->check_dll,"stop"); line_proc = new judgm_proc(info->judgk_modfd,info->run_path,exe_path,set_timelimit,(set_timelimit * 10 + 5000),set_memlimit,chk_proc_fn); - snprintf(data_path,sizeof(data_path),"%s/private/%d",info->pro_path,set_data->test_id); + snprintf(data_path,sizeof(data_path),"%s/private/%d",info->pro_path,set_data->id); if(chk_init_fn(info->judgk_modfd,data_path,info->run_path)){ delete line_proc; return -1; diff --git a/toj/center/src/jmod_test_line.h b/toj/center/src/jmod_test_line.h index c09a503..c09a503 100644..100755 --- a/toj/center/src/jmod_test_line.h +++ b/toj/center/src/jmod_test_line.h diff --git a/toj/center/src/jmod_test_manage.cpp b/toj/center/src/jmod_test_manage.cpp index a1e0a33..e77adc9 100644..100755 --- a/toj/center/src/jmod_test_manage.cpp +++ b/toj/center/src/jmod_test_manage.cpp @@ -29,42 +29,40 @@ static int manage_load_setfile(FILE *set_file,int &count){ return 0; } -DLL_PUBLIC int submit(judgm_manage_submitinfo *info,void **manage_data){ +DLL_PUBLIC int submit(judgm_manage_info *info,FILE *set_file){ int i; int count; manage_result_info *res_info; line_set_data set_data; - manage_load_setfile(info->set_file,count); + manage_load_setfile(set_file,count); res_info = new manage_result_info(count); - *manage_data = res_info; + info->private_data = res_info; for(i = 0;i < count;i++){ - set_data.test_id = i + 1; + set_data.id = i + 1; manage_queuesubmit_fn(info->subid,info->proid,info->lang,(char*)&set_data,sizeof(line_set_data)); } return 0; } -DLL_PUBLIC int result(judgm_manage_resultinfo *info,void *manage_data){ +DLL_PUBLIC int result(judgm_manage_info *info,line_result_data *res_data){ manage_result_info *res_info; - line_result_data *res_data; json_object *jso_item; char tpath[PATH_MAX + 1]; - res_info = (manage_result_info*)manage_data; - res_info->test_count++; + res_info = (manage_result_info*)info->private_data; + res_info->count++; - res_data = (line_result_data*)info->res_data; - if(res_data->status > res_info->test_result){ - res_info->test_result = res_data->status; + if(res_data->status > res_info->result){ + res_info->result = res_data->status; } - res_info->test_totalscore += res_data->score; - res_info->test_totalruntime += res_data->runtime; - if(res_data->memory > res_info->test_maxmemory){ - res_info->test_maxmemory = res_data->memory; + res_info->totalscore += res_data->score; + res_info->totalruntime += res_data->runtime; + if(res_data->memory > res_info->maxmemory){ + res_info->maxmemory = res_data->memory; } jso_item = json_object_new_object(); @@ -73,22 +71,22 @@ DLL_PUBLIC int result(judgm_manage_resultinfo *info,void *manage_data){ json_object_object_add(jso_item,"runtime",json_object_new_int64(res_data->runtime)); json_object_object_add(jso_item,"memory",json_object_new_int64(res_data->memory / 1024UL)); if(strlen(res_data->err_msg) > 0){ + printf(" strlen %d\n",strlen(res_data->err_msg)); json_object_object_add(jso_item,"errmsg",json_object_new_string(res_data->err_msg)); } - json_object_array_put_idx(res_info->jso_resarray,res_data->test_id - 1,jso_item); + json_object_array_put_idx(res_info->jso_resarray,res_data->id - 1,jso_item); - printf("jmod count %d %d\n",res_info->test_count,res_info->test_allcount); - if(res_info->test_count == res_info->test_allcount){ + printf("jmod count %d %d\n",res_info->count,res_info->allcount); + + if(res_info->count == res_info->allcount){ snprintf(tpath,sizeof(tpath),"%s/result",info->res_path); json_object_to_file_ext(tpath,res_info->jso_res,JSON_C_TO_STRING_PLAIN); - info->result = res_info->test_result; - info->score = res_info->test_totalscore; - info->runtime = res_info->test_totalruntime; - info->memory = res_info->test_maxmemory; + info->result = res_info->result; + info->score = res_info->totalscore; + info->runtime = res_info->totalruntime; + info->memory = res_info->maxmemory; - printf("finish result\n"); - delete res_info; return 1; } diff --git a/toj/center/src/jmod_test_manage.h b/toj/center/src/jmod_test_manage.h index 811274a..b0244e3 100644..100755 --- a/toj/center/src/jmod_test_manage.h +++ b/toj/center/src/jmod_test_manage.h @@ -1,21 +1,21 @@ class manage_result_info{ public: - int test_allcount; - int test_count; - int test_result; - double test_totalscore; - unsigned long test_totalruntime; - unsigned long test_maxmemory; + int allcount; + int count; + int result; + double totalscore; + unsigned long totalruntime; + unsigned long maxmemory; json_object *jso_res; json_object *jso_resarray; manage_result_info(int allcount){ - this->test_allcount = allcount; - this->test_count = 0; - this->test_result = JUDGE_AC; - this->test_totalscore = 0; - this->test_totalruntime = 0; - this->test_maxmemory = 0; + this->allcount = allcount; + this->count = 0; + this->result = JUDGE_AC; + this->totalscore = 0; + this->totalruntime = 0; + this->maxmemory = 0; this->jso_res = json_object_new_object(); this->jso_resarray = json_object_new_array(); @@ -26,8 +26,8 @@ public: } }; -DLL_PUBLIC int submit(judgm_manage_submitinfo *info,void **manage_data); -DLL_PUBLIC int result(judgm_manage_resultinfo *info,void *manage_data); +DLL_PUBLIC int submit(judgm_manage_info *info,FILE *set_file); +DLL_PUBLIC int result(judgm_manage_info *info,line_result_data *res_data); static void __attribute__ ((constructor)) manage_init(); static int manage_load_setfile(FILE *setfile,int &count); diff --git a/toj/center/src/judge.h b/toj/center/src/judge.h new file mode 100644 index 0000000..5183942 --- /dev/null +++ b/toj/center/src/judge.h @@ -0,0 +1,44 @@ +#ifndef JUDGE_H +#define JUDGE_H + +#define JUDGE_THREAD_MAX 16 +#define JUDGE_THREAD_JUDGEMAX 2 + +#define JUDGE_CACHESTATE_READY 0 +#define JUDGE_CACHESTATE_UPDATE 1 + +class judge_pro_info{ +public: + int proid; + int cacheid; + int ref_count; + + int state; + int update_cacheid; + + judge_pro_info(int proid,int cacheid){ + this->proid = proid; + this->cacheid = cacheid; + this->ref_count = 0; + + this->state = JUDGE_CACHESTATE_READY; + this->update_cacheid = 0; + } +}; + +class judge_submit_info{ +public: + int subid; + judge_pro_info *pro_info; + int lang; + char *set_data; + + judge_submit_info(int subid,judge_pro_info *pro_info,int lang,char *set_data){ + this->subid = subid; + this->pro_info = pro_info; + this->lang = lang; + this->set_data = set_data; + } +}; + +#endif diff --git a/toj/center/src/judge_def.h b/toj/center/src/judge_def.h index fad8c4d..f0722d0 100755 --- a/toj/center/src/judge_def.h +++ b/toj/center/src/judge_def.h @@ -13,6 +13,7 @@ #define JUDGE_JAVA 0x2 #define JUDGE_PASCEL 0x4 +#define JUDGE_SUB_PARAMMAX 4096 #define JUDGE_SET_FILEMAX 65536 #define JUDGE_SET_DATAMAX 4096 #define JUDGE_RES_DATAMAX 65536 diff --git a/toj/center/src/judge_manage.cpp b/toj/center/src/judge_manage.cpp new file mode 100644 index 0000000..6901565 --- /dev/null +++ b/toj/center/src/judge_manage.cpp @@ -0,0 +1,371 @@ +#include<stdio.h> +#include<stdlib.h> +#include<string.h> +#include<unistd.h> +#include<limits.h> +#include<dirent.h> +#include<dlfcn.h> +#include<sys/types.h> +#include<sys/stat.h> +#include<sys/mman.h> +#include<map> + +#include"tpool.h" +#include"judge_def.h" +#include"judge.h" +#include"judgm_line.h" +#include"judgm_lib.h" +#include"judge_manage.h" + +int judge_manage_init(){ + int i; + + manage_tp = new tpool(JUDGE_THREAD_MAX); + judge_server_addtpool(manage_tp); + manage_tp->start(); + + manage_judgk_modfd = open("/dev/judgk",O_RDWR); + for(i = 0;i < JUDGE_THREAD_JUDGEMAX;i++){ + manage_judgepool[i] = new manage_judgeth_info(i); + } + manage_updatepro_thfn = new tpool_static_fn(manage_updatepro_th); + manage_updatepro_cbfn = new tpool_static_fn(manage_updatepro_cb); + manage_unpackcode_thfn = new tpool_static_fn(manage_unpackcode_th); + manage_unpackcode_cbfn = new tpool_static_fn(manage_unpackcode_cb); + manage_judge_thfn = new tpool_static_fn(manage_judge_th); + manage_judge_cbfn = new tpool_static_fn(manage_judge_cb); + + judge_manage_updatedata(); + return 0; +} +int judge_manage_updatedata(){ + DIR *dirp; + char *buf; + dirent *entry; + int proid; + int cacheid; + judge_pro_info *pro_info; + + if((dirp = opendir("tmp/pro")) == NULL){ + return -1; + } + buf = new char[sizeof(dirent) + NAME_MAX + 1]; + + while(true){ + readdir_r(dirp,(dirent*)buf,&entry); + if(entry == NULL){ + break; + } + if(strcmp(entry->d_name,".") == 0 || strcmp(entry->d_name,"..") == 0){ + continue; + } + + if(entry->d_type == DT_DIR){ + sscanf(entry->d_name,"%d_%d",&proid,&cacheid); + pro_info = new judge_pro_info(proid,cacheid); + judge_manage_getpro(pro_info); + judge_manage_promap.insert(std::make_pair(proid,pro_info)); + } + } + + delete(buf); + closedir(dirp); + + return 0; +} + +judge_pro_info* judge_manage_getprobyid(int proid){ + std::map<int,judge_pro_info*>::iterator pro_it; + judge_pro_info *pro_info; + + if((pro_it = judge_manage_promap.find(proid)) == judge_manage_promap.end()){ + return NULL; + } + pro_info = pro_it->second; + + if(judge_manage_getpro(pro_info)){ + return NULL; + } + + return pro_info; +} +int judge_manage_getpro(judge_pro_info *pro_info){ + pro_info->ref_count++; + return 0; +} +int judge_manage_putpro(judge_pro_info *pro_info){ + std::map<int,judge_pro_info*> pro_it; + char tpath[PATH_MAX + 1]; + char src_path[PATH_MAX + 1]; + + pro_info->ref_count--; + if(pro_info->ref_count == 0){ + snprintf(tpath,sizeof(tpath),"tmp/pro/%d_%d",pro_info->proid,pro_info->cacheid); + tool_cleardir(tpath); + rmdir(tpath); + + delete pro_info; + } + return 0; +} +int judge_manage_updatepro(int proid,int cacheid,bool check_flag,judge_pro_info **update_pro_info){ //If check_flag = true, just check + int ret; + + std::map<int,judge_pro_info*>::iterator pro_it; + judge_pro_info *old_pro_info; + + if((pro_it = judge_manage_promap.find(proid)) == judge_manage_promap.end()){ + if(check_flag == true){ + return 0; + } + }else{ + old_pro_info = pro_it->second; + + if(old_pro_info->state == JUDGE_CACHESTATE_READY && cacheid == old_pro_info->cacheid){ + return 1; + } + if(old_pro_info->state == JUDGE_CACHESTATE_UPDATE && (cacheid <= old_pro_info->cacheid || cacheid <= old_pro_info->update_cacheid)){ + return -1; + } + + if(check_flag == true){ + return 0; + } + + old_pro_info->update_cacheid = cacheid; + old_pro_info->state = JUDGE_CACHESTATE_UPDATE; + } + + *update_pro_info = new judge_pro_info(proid,cacheid); + judge_manage_getpro(*update_pro_info); + + return 0; +} +int judge_manage_done_updatepro(judge_pro_info *pro_info){ + manage_tp->add(manage_updatepro_thfn,pro_info,manage_updatepro_cbfn,pro_info); + return 0; +} +static void manage_updatepro_th(void *data){ + judge_pro_info *pro_info; + int proid; + int cacheid; + char pack_path[PATH_MAX + 1]; + char dir_path[PATH_MAX + 1]; + char tpath[PATH_MAX + 1]; + FILE *f; + + pro_info = (judge_pro_info*)data; + + snprintf(pack_path,sizeof(pack_path),"tmp/propack/%d_%d.tar.bz2",pro_info->proid,pro_info->cacheid); + snprintf(dir_path,sizeof(dir_path),"tmp/pro/%d_%d",pro_info->proid,pro_info->cacheid); + mkdir(dir_path,0755); + tool_cleardir(dir_path); + tool_unpack(pack_path,dir_path); + //unlink(pack_path); + + snprintf(tpath,sizeof(tpath),"tmp/pro/%d_%d/cacheinfo",pro_info->proid,pro_info->cacheid); + f = fopen(tpath,"w"); + fprintf(f,"%d",pro_info->cacheid); + fclose(f); +} +static void manage_updatepro_cb(void *data){ + judge_pro_info *old_pro_info; + judge_pro_info *update_pro_info; + std::pair<std::map<int,judge_pro_info*>::iterator,bool> ins_ret; + std::vector<std::pair<int,int> > pro_list; + + update_pro_info = (judge_pro_info*)data; + + ins_ret = judge_manage_promap.insert(std::make_pair(update_pro_info->proid,update_pro_info)); + if(ins_ret.second == false){ + old_pro_info = ins_ret.first->second; + + if(update_pro_info->cacheid < old_pro_info->cacheid){ + judge_manage_putpro(update_pro_info); + return; + } + + judge_manage_putpro(ins_ret.first->second); + ins_ret.first->second = update_pro_info; + } + + pro_list.push_back(std::make_pair(update_pro_info->proid,update_pro_info->cacheid)); + judge_server_setpro(pro_list); +} + + +int judge_manage_submit(int subid,int proid,int lang,char *set_data){ + judge_pro_info *pro_info; + judge_submit_info *sub_info; + + char tpath[PATH_MAX + 1]; + struct stat st; + + pro_info = judge_manage_getprobyid(proid); + sub_info = new judge_submit_info(subid,pro_info,lang,set_data); + + if(manage_submap.find(subid) == manage_submap.end()){ + snprintf(tpath,sizeof(tpath),"tmp/code/%d",subid); + if(!stat(tpath,&st)){ + manage_queuejudge(sub_info); + }else{ + judge_server_reqcode(subid); + manage_submap.insert(std::make_pair(subid,sub_info)); + } + }else{ + manage_submap.insert(std::make_pair(subid,sub_info)); + } + + return 0; +} +int judge_manage_done_code(int subid){ + manage_tp->add(manage_unpackcode_thfn,(void*)((long)subid),manage_unpackcode_cbfn,(void*)((long)subid)); + return 0; +} +static void manage_unpackcode_th(void *data){ + int subid; + char pack_path[PATH_MAX + 1]; + char dir_path[PATH_MAX + 1]; + char tpath[PATH_MAX + 1]; + FILE *f; + + subid = (int)((long)data); + + snprintf(pack_path,sizeof(pack_path),"tmp/codepack/%d.tar.bz2",subid); + snprintf(dir_path,sizeof(dir_path),"tmp/code/%d",subid); + mkdir(dir_path,0755); + tool_cleardir(dir_path); + tool_unpack(pack_path,dir_path); +} +static void manage_unpackcode_cb(void *data){ + int subid; + std::multimap<int,judge_submit_info*>::iterator sub_it; + judge_submit_info *sub_info; + + subid = (int)((long)data); + + while((sub_it = manage_submap.find(subid)) != manage_submap.end()){ + sub_info = sub_it->second; + manage_queuejudge(sub_info); + manage_submap.erase(sub_it); + } +} +static int manage_queuejudge(judge_submit_info *sub_info){ + int i; + + printf("queue judge %d %d\n",sub_info->subid,sub_info->pro_info->proid); + for(i = 0;i < 16;i++){ + if(manage_judgepool[i]->use_flag == false){ + manage_judgepool[i]->use_flag = true; + manage_judgepool[i]->sub_info = sub_info; + manage_tp->add(manage_judge_thfn,manage_judgepool[i],manage_judge_cbfn,manage_judgepool[i]); + break; + } + } + + return 0; +} +static void manage_judge_th(void *data){ + manage_judgeth_info *th_info; + judge_submit_info *sub_info; + judge_pro_info *pro_info; + char pro_path[PATH_MAX + 1]; + char code_path[PATH_MAX + 1]; + char *set_data; + + th_info = (manage_judgeth_info*)data; + sub_info = th_info->sub_info; + pro_info = sub_info->pro_info; + + snprintf(pro_path,sizeof(pro_path),"tmp/pro/%d_%d",pro_info->proid,pro_info->cacheid); + snprintf(code_path,sizeof(code_path),"tmp/code/%d",sub_info->subid); + manage_judge(sub_info->subid,pro_path,code_path,th_info->run_path,sub_info->lang,sub_info->set_data,th_info->res_data,th_info->res_len); +} +static void manage_judge_cb(void *data){ + manage_judgeth_info *th_info; + judge_submit_info *sub_info; + std::vector<std::pair<int,int> > pro_list; + + th_info = (manage_judgeth_info*)data; + sub_info = th_info->sub_info; + + judge_server_result(sub_info->subid,th_info->res_data,th_info->res_len); + judge_manage_putpro(sub_info->pro_info); + + th_info->use_flag = false; + th_info->sub_info = NULL; + delete sub_info; +} +static int manage_judge(int subid,char *pro_path,char *code_path,char *run_path,int lang,char *set_data,char *res_data,size_t &res_len){ + judgm_line_info *line_info; + int pid; + + char tpath[PATH_MAX + 1]; + FILE *set_file; + char cwd_path[PATH_MAX + 1]; + char jmod_name[NAME_MAX + 1]; + char line_path[PATH_MAX + 1]; + char check_name[NAME_MAX + 1]; + char check_path[PATH_MAX + 1]; + char lchr; + char tchr; + + void *line_dll; + void *check_dll; + judgm_line_run_fn run_fn; + + snprintf(tpath,sizeof(tpath),"%s/setting",pro_path); + set_file = fopen(tpath,"r"); + + getcwd(cwd_path,sizeof(cwd_path)); + fscanf(set_file,"%s",jmod_name); + snprintf(line_path,sizeof(line_path),"%s/tmp/jmod/%s/%s_line.so",cwd_path,jmod_name,jmod_name); + fscanf(set_file,"%s",check_name); + if(check_name[0] == '/'){ + snprintf(check_path,sizeof(check_path),"%s/%s/private%s.so",cwd_path,pro_path,check_name); + }else{ + snprintf(check_path,sizeof(check_path),"%s/tmp/jmod/%s/%s.so",cwd_path,jmod_name,check_name); + } + + lchr = '\n'; + while((tchr = fgetc(set_file)) != EOF){ + if(lchr == '\n' && tchr == '='){ + while(fgetc(set_file) != '\n'); + break; + } + lchr = tchr; + } + + line_dll = dlopen(line_path,RTLD_NOW); + check_dll = dlopen(check_path,RTLD_NOW); + + line_info = (judgm_line_info*)mmap(NULL,sizeof(struct judgm_line_info),PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANONYMOUS,-1,0); + line_info->subid = subid; + line_info->pro_path = pro_path; + line_info->code_path = code_path; + line_info->run_path = run_path; + + line_info->judgk_modfd = manage_judgk_modfd; + line_info->line_dll = line_dll; + line_info->check_dll = check_dll; + + line_info->lang = lang; + line_info->set_file = set_file; + line_info->set_data = set_data; + + tool_cleardir(line_info->run_path); + + run_fn = (judgm_line_run_fn)dlsym(line_dll,"run"); + if((pid = fork()) == 0){ + run_fn(line_info); + exit(0); + } + waitpid(pid,NULL,0); + + memcpy(res_data,line_info->res_data,line_info->res_len); + res_len = line_info->res_len; + + munmap(line_info,sizeof(judgm_line_info)); + fclose(set_file); + return 0; +} diff --git a/toj/center/src/judge_manage.h b/toj/center/src/judge_manage.h new file mode 100644 index 0000000..00abc22 --- /dev/null +++ b/toj/center/src/judge_manage.h @@ -0,0 +1,60 @@ +class manage_judgeth_info{ +public: + bool use_flag; + int thid; + char run_path[PATH_MAX + 1]; + judge_submit_info *sub_info; + char res_data[JUDGE_RES_DATAMAX]; + size_t res_len; + + manage_judgeth_info(int thid){ + this->use_flag = false; + this->thid = thid; + snprintf(this->run_path,sizeof(this->run_path),"tmp/run/%d",thid); + mkdir(this->run_path,0775); + this->sub_info = NULL; + this->res_len = 0; + } +}; + +static void manage_updatepro_th(void *data); +static void manage_updatepro_cb(void *data); +static void manage_unpackcode_th(void *data); +static void manage_unpackcode_cb(void *data); +static void manage_judge_th(void *data); +static void manage_judge_cb(void *data); +static int manage_queuejudge(judge_submit_info *sub_info); +static int manage_judge(int subid,char *pro_path,char *code_path,char *run_path,int lang,char *set_data,char *res_data,size_t &res_len); + +static tpool *manage_tp; +static int manage_judgk_modfd; +static manage_judgeth_info *manage_judgepool[16]; +static tpool_static_fn *manage_updatepro_thfn; +static tpool_static_fn *manage_updatepro_cbfn; +static tpool_static_fn *manage_unpackcode_thfn; +static tpool_static_fn *manage_unpackcode_cbfn; +static tpool_static_fn *manage_judge_thfn; +static tpool_static_fn *manage_judge_cbfn; +static std::multimap<int,judge_submit_info*> manage_submap; + +int judge_manage_init(); +int judge_manage_updatedata(); +judge_pro_info* judge_manage_getprobyid(int proid); +int judge_manage_getpro(judge_pro_info *pro_info); +int judge_manage_putpro(judge_pro_info *pro_info); +int judge_manage_updatepro(int proid,int cacheid,bool check_flag,judge_pro_info **update_pro_info); +int judge_manage_done_updatepro(judge_pro_info *pro_info); +int judge_manage_submit(int subid,int proid,int lang,char *set_data); +int judge_manage_done_code(int subid); + +std::map<int,judge_pro_info*> judge_manage_promap; + +extern int tool_pack(char *pack_path,char *dir_path); +extern int tool_unpack(char *pack_path,char *dir_path); +extern int tool_cleardir(char *path); + +extern int judge_server_addtpool(tpool *tpinfo); +extern int judge_server_setpro(std::vector<std::pair<int,int> > &pro_list); +extern int judge_server_reqpro(int subid); +extern int judge_server_reqcode(int subid); +extern int judge_server_result(int subid,char *res_data,int res_len); diff --git a/toj/center/src/judge_server.cpp b/toj/center/src/judge_server.cpp index f5e6d6d..7a2bb6a 100644..100755 --- a/toj/center/src/judge_server.cpp +++ b/toj/center/src/judge_server.cpp @@ -6,7 +6,6 @@ #include<dlfcn.h> #include<signal.h> #include<limits.h> -#include<ftw.h> #include<pthread.h> #include<semaphore.h> #include<errno.h> @@ -21,9 +20,10 @@ #include<map> #include<queue> -#include"judge_def.h" #include"netio.h" #include"tpool.h" +#include"judge_def.h" +#include"judge.h" #include"center_com.h" #include"judgm_line.h" #include"judgm_lib.h" @@ -48,14 +48,8 @@ server_conn::server_conn(int fd):netio(fd){ this->done_sendjmod_fn = new netio_iofn<server_conn>(this,&server_conn::done_sendjmod); this->recv_sendcode_fn = new netio_iofn<server_conn>(this,&server_conn::recv_sendcode); this->done_sendcode_fn = new netio_iofn<server_conn>(this,&server_conn::done_sendcode); - this->tp_unpackpro_thfn = new tpool_fn<server_conn>(this,&server_conn::tp_unpackpro_th); - this->tp_unpackpro_cbfn = new tpool_fn<server_conn>(this,&server_conn::tp_unpackpro_cb); this->tp_unpackjmod_thfn = new tpool_fn<server_conn>(this,&server_conn::tp_unpackjmod_th); this->tp_unpackjmod_cbfn = new tpool_fn<server_conn>(this,&server_conn::tp_unpackjmod_cb); - this->tp_unpackcode_thfn = new tpool_fn<server_conn>(this,&server_conn::tp_unpackcode_th); - this->tp_unpackcode_cbfn = new tpool_fn<server_conn>(this,&server_conn::tp_unpackcode_cb); - this->tp_judge_thfn = new tpool_fn<server_conn>(this,&server_conn::tp_judge_th); - this->tp_judge_cbfn = new tpool_fn<server_conn>(this,&server_conn::tp_judge_cb); send_setid(); } @@ -110,16 +104,30 @@ int server_conn::send_result(int subid,char *res_data,size_t res_len){ return 0; } -int server_conn::send_setpro(int *proid,int *cacheid,int type,int count){ +int server_conn::send_reqpro(int proid,int cacheid){ + char *write_buf; + int write_len; + center_com_reqpro *reqpro; + + write_buf = create_combuf(CENTER_COMCODE_REQPRO,sizeof(center_com_reqpro),write_len,(void**)&reqpro); + reqpro->proid = proid; + reqpro->cacheid = cacheid; + writebytes(write_buf,write_len,NULL,NULL); +} +int server_conn::send_setpro(std::vector<std::pair<int,int> > &pro_list,int type){ int i; + int count; char *write_buf; int write_len; center_com_setpro *setpro; + judge_pro_info *pro_info; + count = pro_list.size(); write_buf = create_combuf(CENTER_COMCODE_SETPRO,sizeof(center_com_setpro) * count,write_len,(void**)&setpro); + for(i = 0;i < count;i++){ - setpro[i].proid = proid[i]; - setpro[i].cacheid = cacheid[i]; + setpro[i].proid = pro_list[i].first; + setpro[i].cacheid = pro_list[i].second; setpro[i].type = type; } writebytes(write_buf,write_len,NULL,NULL); @@ -144,6 +152,17 @@ int server_conn::send_setjmod(char **jmod_name,int *cacheid,int type,int count){ return 0; } +int server_conn::send_reqcode(int subid){ + char *write_buf; + int write_len; + center_com_reqcode *reqcode; + + write_buf = create_combuf(CENTER_COMCODE_REQCODE,sizeof(center_com_reqcode),write_len,(void**)&reqcode); + reqcode->subid = subid; + writebytes(write_buf,write_len,NULL,NULL); + + return 0; +} int server_conn::readidle(){ readbytes(new center_com_header,sizeof(center_com_header),recv_dispatch_fn,NULL); return 0; @@ -195,33 +214,14 @@ void server_conn::recv_setid(void *buf,size_t len,void *data){ } void server_conn::recv_submit(void *buf,size_t len,void *data){ center_com_submit *sub; - char *write_buf; - int write_len; - center_com_reqcode *reqcode; - std::multimap<int,center_com_submit*>::iterator sub_it; - char tpath[PATH_MAX + 1]; - struct stat st; sub = (center_com_submit*)buf; - if(server_codeconn == NULL){ - server_codeconn = server_connect(); - } + judge_manage_submit(sub->subid,sub->proid,sub->lang,(char*)((char*)buf + sizeof(center_com_submit))); - if(server_submap.find(sub->subid) == server_submap.end()){ - snprintf(tpath,sizeof(tpath),"tmp/code/%d",sub->subid); - if(!stat(tpath,&st)){ - server_queuejudge(sub,tp_judge_thfn,tp_judge_cbfn); - }else{ - write_buf = create_combuf(CENTER_COMCODE_REQCODE,sizeof(center_com_submit),write_len,(void**)&reqcode); - reqcode->subid = sub->subid; - writebytes(write_buf,write_len,NULL,NULL); - server_submap.insert(std::pair<int,center_com_submit*>(sub->subid,sub)); - } - }else{ - server_submap.insert(std::pair<int,center_com_submit*>(sub->subid,sub)); - } + delete sub; } void server_conn::recv_setpro(void *buf,size_t len,void *data){ + int ret; int i; int count; center_com_setpro *setpro; @@ -229,65 +229,55 @@ void server_conn::recv_setpro(void *buf,size_t len,void *data){ char tpath[PATH_MAX + 1]; FILE *f; int cacheid; - std::vector<int> sl_proid; - std::vector<int> sl_cacheid; - - char *write_buf; - int write_len; - center_com_reqpro *reqpro; + std::vector<std::pair<int,int> > pro_list; count = len / sizeof(center_com_setpro); setpro = (center_com_setpro*)buf; for(i = 0;i < count;i++){ if(setpro[i].type == 0){ - snprintf(tpath,sizeof(tpath),"tmp/pro/%d/cacheinfo",setpro[i].proid); - f = fopen(tpath,"r"); - if(f != NULL){ - fscanf(f,"%d",&cacheid); - fclose(f); - - if(cacheid == setpro[i].cacheid){ - sl_proid.push_back(setpro[i].proid); - sl_cacheid.push_back(setpro[i].cacheid); - continue; + ret = judge_manage_updatepro(setpro[i].proid,setpro[i].cacheid,true,NULL); + if(ret == 0){ + if(server_fileconn == NULL){ + server_fileconn = server_connect(); } + server_fileconn->send_reqpro(setpro[i].proid,setpro[i].cacheid); + }else if(ret == 1){ + pro_list.push_back(std::make_pair(setpro[i].proid,setpro[i].cacheid)); } - - if(server_fileconn == NULL){ - server_fileconn = server_connect(); - } - - write_buf = create_combuf(CENTER_COMCODE_REQPRO,sizeof(center_com_reqpro),write_len,(void**)&reqpro); - reqpro->proid = setpro[i].proid; - server_fileconn->writebytes(write_buf,write_len,NULL,NULL); }else if(setpro[i].type == 1){ } } - if(!sl_proid.empty()){ - this->send_setpro(&sl_proid[0],&sl_cacheid[0],0,sl_proid.size()); + if(!pro_list.empty()){ + this->send_setpro(pro_list,0); } delete setpro; } void server_conn::recv_sendpro(void *buf,size_t len,void *data){ center_com_sendpro *sendpro; + judge_pro_info *pro_info; char tpath[PATH_MAX + 1]; int fd; sendpro = (center_com_sendpro*)buf; - snprintf(tpath,sizeof(tpath),"tmp/propack/%d.tar.bz2",sendpro->proid); - fd = open(tpath,O_WRONLY | O_CREAT,0644); - readfile(fd,sendpro->filesize,done_sendpro_fn,sendpro); + + if(judge_manage_updatepro(sendpro->proid,sendpro->cacheid,false,&pro_info) == 0){ + snprintf(tpath,sizeof(tpath),"tmp/propack/%d_%d.tar.bz2",sendpro->proid,sendpro->cacheid); + fd = open(tpath,O_WRONLY | O_CREAT,0644); + readfile(fd,sendpro->filesize,done_sendpro_fn,pro_info); + } + + delete sendpro; } void server_conn::done_sendpro(void *buf,size_t len,void *data){ - center_com_sendpro *sendpro; + judge_pro_info *pro_info; close(*(int*)buf); - sendpro = (center_com_sendpro*)data; - server_packtp->add(tp_unpackpro_thfn,sendpro,tp_unpackpro_cbfn,sendpro); + pro_info = (judge_pro_info*)data; + judge_manage_done_updatepro(pro_info); } void server_conn::recv_setjmod(void *buf,size_t len,void *data){ int i; @@ -374,36 +364,9 @@ void server_conn::done_sendcode(void *buf,size_t len,void *data){ close(*(int*)buf); sendcode = (center_com_sendcode*)data; - server_packtp->add(tp_unpackcode_thfn,sendcode,tp_unpackcode_cbfn,sendcode); -} -void server_conn::tp_unpackpro_th(void *data){ - center_com_sendpro *sendpro; - char pack_path[PATH_MAX + 1]; - char dir_path[PATH_MAX + 1]; - char tpath[PATH_MAX + 1]; - FILE *f; - - sendpro = (center_com_sendpro*)data; - - snprintf(pack_path,sizeof(pack_path),"tmp/propack/%d.tar.bz2",sendpro->proid); - snprintf(dir_path,sizeof(dir_path),"tmp/pro/%d",sendpro->proid); - - mkdir(dir_path,0755); - server_cleardir(dir_path); - pack_unpack(pack_path,dir_path); + judge_manage_done_code(sendcode->subid); - snprintf(tpath,sizeof(tpath),"tmp/pro/%d/cacheinfo",sendpro->proid); - f = fopen(tpath,"w"); - fprintf(f,"%d",sendpro->cacheid); - fclose(f); -} -void server_conn::tp_unpackpro_cb(void *data){ - center_com_sendpro *sendpro; - - sendpro = (center_com_sendpro*)data; - send_setpro(&sendpro->proid,&sendpro->cacheid,0,1); - - delete sendpro; + delete sendcode; } void server_conn::tp_unpackjmod_th(void *data){ center_com_sendjmod *sendjmod; @@ -417,8 +380,8 @@ void server_conn::tp_unpackjmod_th(void *data){ snprintf(pack_path,sizeof(pack_path),"tmp/jmodpack/%s.tar.bz2",sendjmod->jmod_name); snprintf(dir_path,sizeof(dir_path),"tmp/jmod/%s",sendjmod->jmod_name); mkdir(dir_path,0755); - server_cleardir(dir_path); - pack_unpack(pack_path,dir_path); + tool_cleardir(dir_path); + tool_unpack(pack_path,dir_path); snprintf(tpath,sizeof(tpath),"tmp/jmod/%s/cacheinfo",sendjmod->jmod_name); f = fopen(tpath,"w"); @@ -435,175 +398,30 @@ void server_conn::tp_unpackjmod_cb(void *data){ delete sendjmod; } -void server_conn::tp_unpackcode_th(void *data){ - center_com_sendcode *sendcode; - char pack_path[PATH_MAX + 1]; - char dir_path[PATH_MAX + 1]; - char tpath[PATH_MAX + 1]; - FILE *f; - - sendcode = (center_com_sendcode*)data; - - snprintf(pack_path,sizeof(pack_path),"tmp/codepack/%d.tar.bz2",sendcode->subid); - snprintf(dir_path,sizeof(dir_path),"tmp/code/%d",sendcode->subid); - mkdir(dir_path,0755); - server_cleardir(dir_path); - pack_unpack(pack_path,dir_path); -} -void server_conn::tp_unpackcode_cb(void *data){ - center_com_sendcode *sendcode; - int subid; - std::multimap<int,center_com_submit*>::iterator sub_it; - center_com_submit *sub; - - sendcode = (center_com_sendcode*)data; - subid = sendcode->subid; - - while((sub_it = server_submap.find(subid)) != server_submap.end()){ - sub = sub_it->second; - server_queuejudge(sub,tp_judge_thfn,tp_judge_cbfn); - server_submap.erase(sub_it); - } - - delete sendcode; -} -void server_conn::tp_judge_th(void *data){ - server_judgeth_info *th_info; - center_com_submit *sub; - char pro_path[PATH_MAX + 1]; - char code_path[PATH_MAX + 1]; - - th_info = (server_judgeth_info*)data; - sub = th_info->sub; - - snprintf(pro_path,sizeof(pro_path),"tmp/pro/%d",sub->proid); - snprintf(code_path,sizeof(code_path),"tmp/code/%d",sub->subid); - server_judge(sub->subid,pro_path,code_path,th_info->run_path,sub->lang,sub->set_data,th_info->res_data,th_info->res_len); -} -void server_conn::tp_judge_cb(void *data){ - server_judgeth_info *th_info; - center_com_submit *sub; - - th_info = (server_judgeth_info*)data; - sub = th_info->sub; - send_result(sub->subid,th_info->res_data,th_info->res_len); - th_info->use_flag = false; - th_info->sub = NULL; - delete sub; -} - -static int server_queuejudge(center_com_submit *sub,tpool_protofn *th_fn,tpool_protofn *cb_fn){ - int i; - - printf("get submit %d %d\n",sub->subid,sub->proid); - for(i = 0;i < 8;i++){ - if(server_judgepool[i]->use_flag == false){ - server_judgepool[i]->use_flag = true; - server_judgepool[i]->sub = sub; - server_judgetp->add(th_fn,server_judgepool[i],cb_fn,server_judgepool[i]); - break; - } - } - +int judge_server_addtpool(tpool *tpinfo){ + server_addepev(tpinfo->fd,EPOLLIN | EPOLLET,SERVER_EPEV_TPOOL,tpinfo); return 0; } -static int server_judge(int subid,char *pro_path,char *code_path,char *run_path,int lang,char *set_data,char *res_data,size_t &res_len){ - judgm_line_info *line_info; - int pid; - - char tpath[PATH_MAX + 1]; - FILE *set_file; - char cwd_path[PATH_MAX + 1]; - char jmod_name[NAME_MAX + 1]; - char line_path[PATH_MAX + 1]; - char check_name[NAME_MAX + 1]; - char check_path[PATH_MAX + 1]; - char lchr; - char tchr; - - int judgk_modfd; - void *line_dll; - void *check_dll; - judgm_line_run_fn run_fn; - - snprintf(tpath,sizeof(tpath),"%s/setting",pro_path); - set_file = fopen(tpath,"r"); - - getcwd(cwd_path,sizeof(cwd_path)); - fscanf(set_file,"%s",jmod_name); - snprintf(line_path,sizeof(line_path),"%s/tmp/jmod/%s/%s_line.so",cwd_path,jmod_name,jmod_name); - fscanf(set_file,"%s",check_name); - if(check_name[0] == '/'){ - snprintf(check_path,sizeof(check_path),"%s/%s/private%s.so",cwd_path,pro_path,check_name); - }else{ - snprintf(check_path,sizeof(check_path),"%s/tmp/jmod/%s/%s.so",cwd_path,jmod_name,check_name); - } - - lchr = '\n'; - while((tchr = fgetc(set_file)) != EOF){ - if(lchr == '\n' && tchr == '='){ - while(fgetc(set_file) != '\n'); - break; - } - lchr = tchr; - } - - judgk_modfd = open("/dev/judgk",O_RDWR); - line_dll = dlopen(line_path,RTLD_NOW); - check_dll = dlopen(check_path,RTLD_NOW); - - line_info = (judgm_line_info*)mmap(NULL,sizeof(struct judgm_line_info),PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANONYMOUS,-1,0); - - line_info->subid = subid; - - line_info->pro_path = pro_path; - line_info->code_path = code_path; - line_info->run_path = run_path; - - line_info->judgk_modfd = judgk_modfd; - line_info->line_dll = line_dll; - line_info->check_dll = check_dll; - - line_info->lang = lang; - line_info->set_file = set_file; - line_info->set_data = set_data; - - server_cleardir(line_info->run_path); - - run_fn = (judgm_line_run_fn)dlsym(line_dll,"run"); - if((pid = fork()) == 0){ - run_fn(line_info); - exit(0); - } - waitpid(pid,NULL,0); - - memcpy(res_data,line_info->res_data,line_info->res_len); - res_len = line_info->res_len; - - munmap(line_info,sizeof(judgm_line_info)); - fclose(set_file); - close(judgk_modfd); +int judge_server_setpro(std::vector<std::pair<int,int> > &pro_list){ + server_mainconn->send_setpro(pro_list,0); return 0; } -static int server_cleardir_callback(const char *path,const struct stat *st,int flag,struct FTW *ftw_buf){ - if(ftw_buf->level == 0){ - return 0; +int judge_server_reqcode(int subid){ + if(server_codeconn == NULL){ + server_codeconn = server_connect(); } + server_codeconn->send_reqcode(subid); - if(S_ISDIR(st->st_mode)){ - rmdir(path); - }else{ - unlink(path); - } return 0; } -static int server_cleardir(char *path){ - nftw(path,server_cleardir_callback,64,FTW_DEPTH | FTW_PHYS); +int judge_server_result(int subid,char *res_data,int res_len){ + server_mainconn->send_result(subid,res_data,res_len); return 0; } + static int server_addepev(int fd,unsigned int flag,int type,void *data){ server_epevdata *epevdata; epoll_event epev; @@ -630,7 +448,7 @@ static server_conn* server_connect(){ caddr.sin_family = AF_INET; caddr.sin_port = htons(SERVER_JUDGE_PORT); //caddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - caddr.sin_addr.s_addr = inet_addr("10.8.0.1"); + caddr.sin_addr.s_addr = inet_addr("10.8.0.2"); cinfo = new server_conn(cfd); server_addepev(cfd,EPOLLIN | EPOLLOUT | EPOLLRDHUP | EPOLLET,SERVER_EPEV_JUDGECLIENT,cinfo); @@ -654,22 +472,18 @@ int main(){ server_epfd = epoll_create1(0); server_id = 0; - server_avail = 2; + server_avail = JUDGE_THREAD_JUDGEMAX; server_mainconn = server_connect(); server_fileconn = NULL; server_codeconn = NULL; + judge_manage_init(); + server_packtp = new tpool(4); + judge_server_addtpool(server_packtp); server_packtp->start(); - server_addepev(server_packtp->fd,EPOLLIN | EPOLLET,SERVER_EPEV_TPOOL,server_packtp); - - for(i = 0;i < 8;i++){ - server_judgepool[i] = new server_judgeth_info(i); - } - server_judgetp = new tpool(8); - server_judgetp->start(); - server_addepev(server_judgetp->fd,EPOLLIN | EPOLLET,SERVER_EPEV_TPOOL,server_judgetp); + while(true){ nevs = epoll_wait(server_epfd,epevs,SERVER_EPOLL_MAXEVENT,-1); for(i = 0;i < nevs;i++){ diff --git a/toj/center/src/judge_server.h b/toj/center/src/judge_server.h index d904d9d..fadde93 100644..100755 --- a/toj/center/src/judge_server.h +++ b/toj/center/src/judge_server.h @@ -25,14 +25,8 @@ private: netio_iofn<server_conn> *done_sendjmod_fn; netio_iofn<server_conn> *recv_sendcode_fn; netio_iofn<server_conn> *done_sendcode_fn; - tpool_fn<server_conn> *tp_unpackpro_thfn; - tpool_fn<server_conn> *tp_unpackpro_cbfn; tpool_fn<server_conn> *tp_unpackjmod_thfn; tpool_fn<server_conn> *tp_unpackjmod_cbfn; - tpool_fn<server_conn> *tp_unpackcode_thfn; - tpool_fn<server_conn> *tp_unpackcode_cbfn; - tpool_fn<server_conn> *tp_judge_thfn; - tpool_fn<server_conn> *tp_judge_cbfn; char* create_combuf(int code,int size,int &len,void **data); void recv_dispatch(void *buf,size_t len,void *data); @@ -46,62 +40,48 @@ private: void done_sendjmod(void *buf,size_t len,void *data); void recv_sendcode(void *buf,size_t len,void *data); void done_sendcode(void *buf,size_t len,void *data); - void tp_unpackpro_th(void *data); - void tp_unpackpro_cb(void *data); void tp_unpackjmod_th(void *data); void tp_unpackjmod_cb(void *data); - void tp_unpackcode_th(void *data); - void tp_unpackcode_cb(void *data); - void tp_judge_th(void *data); - void tp_judge_cb(void *data); public: server_conn(int fd); int send_setid(); int send_setinfo(); int send_result(int subid,char *res_data,size_t res_len); - int send_setpro(int *proid,int *cacheid,int type,int count); + int send_reqpro(int proid,int cacheid); + int send_setpro(std::vector<std::pair<int,int> > &pro_list,int type); int send_setjmod(char **jmod_name,int *cacheid,int type,int count); + int send_reqcode(int subid); virtual int readidle(); }; -class server_judgeth_info{ -public: - bool use_flag; - int thid; - char run_path[PATH_MAX + 1]; - center_com_submit *sub; - char res_data[JUDGE_RES_DATAMAX]; - size_t res_len; - - server_judgeth_info(int thid){ - this->use_flag = false; - this->thid = thid; - snprintf(this->run_path,sizeof(this->run_path),"tmp/run/%d",thid); - mkdir(this->run_path,0775); - this->sub = NULL; - this->res_len = 0; - } -}; - -static int server_queuejudge(center_com_submit *sub,tpool_protofn *th_fn,tpool_protofn *cb_fn); -static int server_judge(int subid,char *pro_path,char *code_path,char *run_path,int lang,char *set_data,char *res_data,size_t &res_len); -static int server_cleardir_callback(const char *path,const struct stat *st,int flag,struct FTW *ftw_buf); -static int server_cleardir(char *path); static int server_addepev(int fd,unsigned int flag,int type,void *data); static int server_delepev(server_epevdata *epevdata); static server_conn* server_connect(); static int server_id; static int server_avail; -static std::multimap<int,center_com_submit*> server_submap; static int server_epfd; static server_conn *server_mainconn; static server_conn *server_fileconn; static server_conn *server_codeconn; static tpool *server_packtp; -static server_judgeth_info *server_judgepool[8]; -static tpool *server_judgetp; -extern int pack_pack(char *pack_path,char *dir_path); -extern int pack_unpack(char *pack_path,char *dir_path); +int judge_server_addtpool(tpool *tpinfo); +int judge_server_setpro(std::vector<std::pair<int,int> > &pro_list); +int judge_server_reqcode(int subid); +int judge_server_result(int subid,char *res_data,int res_len); + +extern int tool_pack(char *pack_path,char *dir_path); +extern int tool_unpack(char *pack_path,char *dir_path); +extern int tool_cleardir(char *path); + +extern int judge_manage_init(); +extern judge_pro_info* judge_manage_getprobyid(int proid); +extern int judge_manage_getpro(judge_pro_info *pro_info); +extern int judge_manage_putpro(judge_pro_info *pro_info); +extern int judge_manage_updatepro(int proid,int cacheid,bool check_flag,judge_pro_info **update_pro_info); +extern int judge_manage_done_updatepro(judge_pro_info *pro_info); +extern int judge_manage_submit(int subid,int proid,int lang,char *set_data); +extern int judge_manage_done_code(int subid); + diff --git a/toj/center/src/judgk_com.h b/toj/center/src/judgk_com.h index 842c69c..842c69c 100644..100755 --- a/toj/center/src/judgk_com.h +++ b/toj/center/src/judgk_com.h diff --git a/toj/center/src/judgk_hyperio.c b/toj/center/src/judgk_hyperio.c index 67b0ef6..67b0ef6 100644..100755 --- a/toj/center/src/judgk_hyperio.c +++ b/toj/center/src/judgk_hyperio.c diff --git a/toj/center/src/judgk_hyperio.h b/toj/center/src/judgk_hyperio.h index ccc1449..ccc1449 100644..100755 --- a/toj/center/src/judgk_hyperio.h +++ b/toj/center/src/judgk_hyperio.h diff --git a/toj/center/src/judgk_security.c b/toj/center/src/judgk_security.c index 8eb54cb..4f0612a 100755 --- a/toj/center/src/judgk_security.c +++ b/toj/center/src/judgk_security.c @@ -180,7 +180,6 @@ int judgk_security_hook(){ hook_sops.secmark_refcount_dec = hook_secmark_refcount_dec; hook_sops.req_classify_flow = hook_req_classify_flow; hook_sops.tun_dev_create = hook_tun_dev_create; - hook_sops.tun_dev_post_create = hook_tun_dev_post_create; hook_sops.tun_dev_attach = hook_tun_dev_attach; hook_sops.key_alloc = hook_key_alloc; hook_sops.key_free = hook_key_free; @@ -321,8 +320,7 @@ static int hook_file_open(struct file *file, const struct cred *cred){ int i; struct judgk_proc_info *info; - char *buf_path - char *path; + char *buf_path,*path; info = judgk_proc_task_lookup(current); if(likely(info == NULL || in_interrupt())){ @@ -2450,24 +2448,12 @@ static int hook_tun_dev_create(){ security_hook_rf(info); return -EACCES; } -static void hook_tun_dev_post_create(struct sock *sk){ +static int hook_tun_dev_attach(struct sock *sk,void *security){ struct judgk_proc_info *info; info = judgk_proc_task_lookup(current); if(likely(info == NULL || in_interrupt())){ - return ori_sops->tun_dev_post_create(sk); - } - - pr_alert("judgk:PID %d tun_dev_post_create\n",current->tgid); - - security_hook_rf(info); -} -static int hook_tun_dev_attach(struct sock *sk){ - struct judgk_proc_info *info; - - info = judgk_proc_task_lookup(current); - if(likely(info == NULL || in_interrupt())){ - return ori_sops->tun_dev_attach(sk); + return ori_sops->tun_dev_attach(sk,security); } pr_alert("judgk:PID %d tun_dev_attach\n",current->tgid); diff --git a/toj/center/src/judgk_security.h b/toj/center/src/judgk_security.h index 61a2808..16d2534 100755 --- a/toj/center/src/judgk_security.h +++ b/toj/center/src/judgk_security.h @@ -176,8 +176,7 @@ static void hook_secmark_refcount_inc(void); static void hook_secmark_refcount_dec(void); static void hook_req_classify_flow(const struct request_sock *req,struct flowi *fl); static int hook_tun_dev_create(void); -static void hook_tun_dev_post_create(struct sock *sk); -static int hook_tun_dev_attach(struct sock *sk); +static int hook_tun_dev_attach(struct sock *sk,void *security); /*static int hook_xfrm_policy_alloc_security(struct xfrm_sec_ctx **ctxp,struct xfrm_user_sec_ctx *sec_ctx); static int hook_xfrm_policy_clone_security(struct xfrm_sec_ctx *old_ctx,struct xfrm_sec_ctx **new_ctx); static void hook_xfrm_policy_free_security(struct xfrm_sec_ctx *ctx); diff --git a/toj/center/src/judgm_lib.h b/toj/center/src/judgm_lib.h index 4aa02fa..2007763 100644..100755 --- a/toj/center/src/judgm_lib.h +++ b/toj/center/src/judgm_lib.h @@ -16,6 +16,7 @@ #include<map> #include<utility> +#include"judge.h" #include"judgk_com.h" typedef int (*judgm_proc_check_fn)(); @@ -65,6 +66,10 @@ private: limit.rlim_max = limit.rlim_cur; prlimit(pid,RLIMIT_NOFILE,&limit,NULL); + limit.rlim_cur = 70368744177664L; + limit.rlim_max = limit.rlim_cur; + prlimit(pid,RLIMIT_STACK,&limit,NULL); + com_proc_add.run_path[0] = '\0'; strncat(com_proc_add.run_path,run_path,sizeof(com_proc_add.run_path)); com_proc_add.pid = pid; @@ -273,6 +278,7 @@ static int judgm_compile(int subid,char *code_path,char *exe_path,int lang,bool int ret; int i; + char log_path[PATH_MAX + 1]; char main_path[PATH_MAX + 1]; char sem_path[PATH_MAX + 1]; struct stat st; @@ -283,9 +289,15 @@ static int judgm_compile(int subid,char *code_path,char *exe_path,int lang,bool int io[2]; int pid; int wstatus; - off_t off; + char buf[64]; + off_t err_off; + FILE *f_log; - if(force_flag == false){ + if(force_flag == true){ + force_flag = true; + out_path = exe_path; + }else{ + snprintf(log_path,sizeof(log_path),"tmp/exe/%d/log",subid); snprintf(main_path,sizeof(main_path),"tmp/exe/%d/main",subid); snprintf(sem_path,sizeof(sem_path),"/judgm_compile_wait_%d",subid); if((wait_sem = sem_open(sem_path,0)) == SEM_FAILED){ @@ -307,14 +319,19 @@ static int judgm_compile(int subid,char *code_path,char *exe_path,int lang,bool sem_close(wait_sem); } - if(!link(main_path,exe_path)){ - return 0; + if((f_log = fopen(log_path,"r")) != NULL){ + err_off = fread(err_msg,1,err_len - 1,f_log); + fclose(f_log); + err_msg[err_off] = '\0'; + + if(!link(main_path,exe_path)){ + return 0; + }else{ + return -1; + } } } - force_flag = true; - out_path = exe_path; - compile: if(force_flag == false){ @@ -322,12 +339,38 @@ compile: mkdir(dir_path,0755); } ce_flag = false; + err_off = 0; if(lang == JUDGE_CPP){ pipe(io); if((pid = fork()) == 0){ - char *argv[] = {"g++","-static","-O2",code_path,"-std=c++0x","-o",out_path,NULL}; + char arg_compiler[16]; + char arg_static[16]; + char arg_o[16]; + char arg_std[16]; + char arg_output[16]; + char *argv[8]; + + arg_compiler[0] = '\0'; + strncat(arg_compiler,"g++",sizeof(arg_compiler)); + arg_static[0] = '\0'; + strncat(arg_static,"-static",sizeof(arg_static)); + arg_o[0] = '\0'; + strncat(arg_o,"-O2",sizeof(arg_o)); + arg_std[0] = '\0'; + strncat(arg_std,"-std=c++0x",sizeof(arg_std)); + arg_output[0] = '\0'; + strncat(arg_output,"-o",sizeof(arg_output)); + + argv[0] = arg_compiler; + argv[1] = arg_static; + argv[2] = arg_o; + argv[3] = code_path; + argv[4] = arg_std; + argv[5] = arg_output; + argv[6] = out_path; + argv[7] = NULL; dup2(io[1],1); dup2(io[1],2); @@ -335,13 +378,20 @@ compile: } close(io[1]); - off = 0; - while((ret = read(io[0],err_msg + off,err_len - off - 1)) > 0){ - off += ret; + while((ret = read(io[0],err_msg + err_off,err_len - err_off - 1)) > 0){ + err_off += ret; } - err_msg[off] = '\0'; + err_msg[err_off] = '\0'; + + while(read(io[0],buf,64) > 0); close(io[0]); + if(err_off > (err_len - 4)){ + err_msg[err_len - 4] = '\0'; + strncat(err_msg + err_len - 4,"...",4); + err_off = err_len - 1; + } + waitpid(pid,&wstatus,0); if(wstatus != 0){ ce_flag = true; @@ -349,11 +399,11 @@ compile: } if(force_flag == false){ - if(ce_flag == true){ - rmdir(dir_path); - } + f_log = fopen(log_path,"w"); + fwrite(err_msg,err_off,1,f_log); + fclose(f_log); - for(i = 0;i < 8;i++){ + for(i = 0;i < JUDGE_THREAD_MAX;i++){ sem_post(wait_sem); } sem_close(wait_sem); diff --git a/toj/center/src/judgm_manage.h b/toj/center/src/judgm_manage.h index 85385e7..2795ec7 100644..100755 --- a/toj/center/src/judgm_manage.h +++ b/toj/center/src/judgm_manage.h @@ -1,27 +1,29 @@ typedef int (*judgm_manage_queuesubmit_fn)(int subid,int proid,int lang,char *set_data,size_t set_len); -struct judgm_manage_submitinfo{ +class judgm_manage_info{ +public: int subid; int uid; int proid; int lang; char *param; - char pro_path[PATH_MAX + 1]; - FILE *set_file; -}; -typedef int (*judgm_manage_submit_fn)(judgm_manage_submitinfo *info,void **manage_data); - -struct judgm_manage_resultinfo{ - int subid; - int uid; - int proid; - char *res_path; - char *res_data; + char res_path[PATH_MAX + 1]; int result; double score; unsigned long runtime; unsigned long memory; + + void *private_data; + + judgm_manage_info(int subid,int uid,int proid,int lang,char *param){ + this->subid = subid; + this->uid = uid; + this->proid = proid; + this->lang = lang; + this->param = param; + } }; -typedef int (*judgm_manage_result_fn)(judgm_manage_resultinfo *info,void *manage_data); +typedef int (*judgm_manage_submit_fn)(judgm_manage_info *info,FILE *set_file); +typedef int (*judgm_manage_result_fn)(judgm_manage_info *info,char *res_data); diff --git a/toj/center/src/netio.h b/toj/center/src/netio.h index db54b23..db54b23 100644..100755 --- a/toj/center/src/netio.h +++ b/toj/center/src/netio.h diff --git a/toj/center/src/pack.cpp b/toj/center/src/tool.cpp index c2206b1..b4a302d 100644 --- a/toj/center/src/pack.cpp +++ b/toj/center/src/tool.cpp @@ -1,13 +1,18 @@ -#include<stdio.h> -#include<stdlib.h> #include<string.h> +#include<dirent.h> #include<unistd.h> #include<fcntl.h> +#include<limits.h> +#include<ftw.h> #include<libtar.h> #include<bzlib.h> +#include<sys/stat.h> +#include<sys/sendfile.h> #include<map> +#include<vector> +#include<string> -#include"pack.h" +#include"tool.h" static int pack_copenfn(const char *pathname,int flags,...){ int fd; @@ -143,33 +148,147 @@ static ssize_t pack_xreadfn(long fd,void *buf,size_t count){ return count - bzinfo->bzs.avail_out; } -int pack_pack(char *packpath,char *dirpath){ - tartype_t tartype; +int tool_pack(char *pack_path,char *dir_path){ + tartype_t tar_type; TAR *tarp; + char tpath[2] = {'.','\0'}; - tartype.openfunc = pack_copenfn; - tartype.closefunc = pack_cclosefn; - tartype.readfunc = (readfunc_t)read; - tartype.writefunc = pack_cwritefn; - tar_open(&tarp,packpath,&tartype,O_WRONLY | O_CREAT,0644,TAR_GNU); + tar_type.openfunc = pack_copenfn; + tar_type.closefunc = pack_cclosefn; + tar_type.readfunc = (readfunc_t)read; + tar_type.writefunc = pack_cwritefn; + tar_open(&tarp,pack_path,&tar_type,O_WRONLY | O_CREAT,0644,TAR_GNU); - tar_append_tree(tarp,dirpath,"."); + tar_append_tree(tarp,dir_path,tpath); tar_close(tarp); return 0; } -int pack_unpack(char *packpath,char *dirpath){ - tartype_t tartype; +int tool_unpack(char *pack_path,char *dir_path){ + tartype_t tar_type; TAR *tarp; - tartype.openfunc = pack_xopenfn; - tartype.closefunc = pack_xclosefn; - tartype.readfunc = pack_xreadfn; - tartype.writefunc = (writefunc_t)write; - tar_open(&tarp,packpath,&tartype,O_RDONLY,0644,TAR_GNU); + tool_cleardir(dir_path); + mkdir(dir_path,0775); - tar_extract_all(tarp,dirpath); + tar_type.openfunc = pack_xopenfn; + tar_type.closefunc = pack_xclosefn; + tar_type.readfunc = pack_xreadfn; + tar_type.writefunc = (writefunc_t)write; + tar_open(&tarp,pack_path,&tar_type,O_RDONLY,0644,TAR_GNU); + + tar_extract_all(tarp,dir_path); tar_close(tarp); return 0; } + +static int cleardir_callback(const char *path,const struct stat *st,int flag,struct FTW *ftw_buf){ + if(ftw_buf->level == 0){ + return 0; + } + + if(S_ISDIR(st->st_mode)){ + rmdir(path); + }else{ + unlink(path); + } + return 0; +} +int tool_cleardir(char *path){ + nftw(path,cleardir_callback,64,FTW_DEPTH | FTW_PHYS); + return 0; +} +static int copydir_travel(char *old_path,int old_len,char *new_path,int new_len){ + int i; + int j; + int len; + + DIR *dirp; + char *buf; + dirent *entry; + std::vector<std::string> wait_list; + const char *tname; + + int infd; + int outfd; + struct stat st; + + if((dirp = opendir(old_path)) == NULL){ + return -1; + } + buf = new char[sizeof(dirent) + NAME_MAX + 1]; + + while(true){ + readdir_r(dirp,(dirent*)buf,&entry); + if(entry == NULL){ + break; + } + if(strcmp(entry->d_name,".") == 0 || strcmp(entry->d_name,"..") == 0){ + continue; + } + + if(entry->d_type == DT_DIR){ + wait_list.push_back(entry->d_name); + }else{ + old_path[old_len] = '/'; + new_path[new_len] = '/'; + len = strlen(entry->d_name); + for(i = 0;i <= len;i++){ + old_path[old_len + i + 1] = entry->d_name[i]; + new_path[new_len + i + 1] = entry->d_name[i]; + } + + infd = open(old_path,O_RDONLY); + outfd = open(new_path,O_WRONLY | O_CREAT); + fstat(infd,&st); + sendfile(outfd,infd,NULL,st.st_size); + close(infd); + close(outfd); + + old_path[old_len] = '\0'; + new_path[new_len] = '\0'; + } + } + + delete buf; + closedir(dirp); + + while(!wait_list.empty()){ + tname = wait_list.back().c_str(); + wait_list.pop_back(); + + old_path[old_len] = '/'; + new_path[new_len] = '/'; + len = strlen(tname); + for(i = 0;i <= len;i++){ + old_path[old_len + i + 1] = tname[i]; + new_path[new_len + i + 1] = tname[i]; + } + + mkdir(new_path,0775); + + copydir_travel(old_path,old_len + len + 1,new_path,new_len + len + 1); + + old_path[old_len] = '\0'; + new_path[new_len] = '\0'; + } + + return 0; +} +int tool_copydir(char *old_path,char *new_path){ + char old_buf[PATH_MAX + 1]; + char new_buf[PATH_MAX + 1]; + + tool_cleardir(new_path); + mkdir(new_path,0775); + + old_buf[0] = '\0'; + strncat(old_buf,old_path,sizeof(old_buf)); + new_buf[0] = '\0'; + strncat(new_buf,new_path,sizeof(new_buf)); + + copydir_travel(old_buf,strlen(old_buf),new_buf,strlen(new_buf)); + + return 0; +} diff --git a/toj/center/src/pack.h b/toj/center/src/tool.h index 8f8ac88..f876c29 100644 --- a/toj/center/src/pack.h +++ b/toj/center/src/tool.h @@ -12,9 +12,15 @@ static int pack_cclosefn(long fd); static ssize_t cpack_writefn(long fd,const void *buf,size_t count); static int pack_xopenfn(const char *pathname,int flags,...); static int pack_xclosefn(long fd); -static ssize_t xpack_readfn(long fd,void *buf,size_t count); +static ssize_t pack_xreadfn(long fd,void *buf,size_t count); static std::map<int,pack_bzinfo*> pack_fdmap; -int pack_pack(char *packpath,char *dirpath); -int pack_unpack(char *packpath,char *dirpath); +int tool_pack(char *pack_path,char *dir_path); +int tool_unpack(char *pack_path,char *dir_path); + +static int cleardir_callback(const char *path,const struct stat *st,int flag,struct FTW *ftw_buf); +static int copydir_travel(char *old_path,int old_len,char *new_path,int new_len); + +int tool_cleardir(char *path); +int tool_copydir(char *old_path,char *new_path); diff --git a/toj/center/src/tpool.h b/toj/center/src/tpool.h index 08aedbc..c06efc1 100644..100755 --- a/toj/center/src/tpool.h +++ b/toj/center/src/tpool.h @@ -1,3 +1,9 @@ +#include<pthread.h> +#include<semaphore.h> +#include<sys/eventfd.h> +#include<queue> +#include<vector> + class tpool_protofn{ public: virtual void operator()(void *data) = 0; diff --git a/toj/index.html b/toj/index.html index 615a7d7..f3894c0 100644..100755 --- a/toj/index.html +++ b/toj/index.html @@ -131,7 +131,7 @@ input,select{ <div id="index_head_nickname" class="nickname"><a class="nickname"></a></div> </div> -<div id="index_panel_box" exheight=true class="index_panel_box"><ul id="index_panel" class="index_panel"> +<div id="index_panel_box" exminheight=true class="index_panel_box"><ul id="index_panel" class="index_panel"> <li class="button home"><a href="/toj/home/" class="button">首頁</a></li> <li class="button stat"><a href="/toj/stat/allsub/" class="button">狀態</a></li> <li class="button user" style="display:none;"><a class="button">個人</a></li> @@ -143,7 +143,7 @@ input,select{ <li class="button logout" style="margin:64px 0px 0px 0px; display:none;"><a href="/toj/logout/" class="button">登出</a></li> </ul></div> -<div id="notice_list_box" exheight=true class="notice_list_box"><ul id="notice_list" class="notice_list"></ul></div> +<div id="notice_list_box" exminheight=true class="notice_list_box"><ul id="notice_list" class="notice_list"></ul></div> <div id="index_page" class="index_page"> @@ -237,6 +237,16 @@ input,select{ <div class="left_box"> <h1>方塊</h1> <button class="newsq">建立方塊</button> + <h1>題目</h1> + <button class="newpro">建立題目</button> + <table class="prolist"> + <tr class="head"> + <th class="proid">ProID</th> + <th class="name">題目名稱</th> + <th class="cacheid">CacheID</th> + <th></th> + </tr> + </table> </div> </div> </div> @@ -321,6 +331,30 @@ input,select{ <button class="delete" style="display:none;">刪除</button> </div> </div> + <div class="com_mbox editpro_mbox"> + <div class="edit_box"> + <h1>基本資料</h1> + <label>題目名稱</label> + <input name="name" type="textbox" size="16" placeholder="foo"> + <label>模組ID</label> + <input name="modid" type="textbox" size="16" placeholder="1"> + <label>隱私</label> + <select name="hidden"> + <option value=1>公開</option> + <option value=2>隱藏</option> + </select> + <div class="update" style="display:none;"> + <h1>更新題目</h1> + <span class="cacheid"></span><br><br> + <button class="update">更新</button> + </div> + + <div class="error"></div> + <button class="submit">確定</button> + <button class="cancel">取消</button> + <button class="delete" style="">刪除</button> + </div> + </div> </div> <div class="pro_mask"> <div exheight=true extop=32 exbottom=32 class="com_mbox sub_mbox"> diff --git a/toj/jcs/common.css b/toj/jcs/common.css index f05adea..f05adea 100644..100755 --- a/toj/jcs/common.css +++ b/toj/jcs/common.css diff --git a/toj/jcs/common.js b/toj/jcs/common.js index 976614c..e1b1d82 100644..100755 --- a/toj/jcs/common.js +++ b/toj/jcs/common.js @@ -126,6 +126,10 @@ var com = new function(){ }; that.url_push = function(url){ + if(url == location.href){ + return; + } + that.url_prev = location.href; that.url_back = that.url_prev; window.history.pushState(null,document.title,url); @@ -139,12 +143,17 @@ var com = new function(){ } }; that.url_update = function(url){ + if(url == location.href){ + return; + } + that.url_prev = location.href; window.history.replaceState(null,document.title,url); com.url_chg(); }; that.url_pull = function(){ - window.history.back(); + that.url_update(that.url_back); + //window.history.back(); }; that.url_chg = function(){ var i; @@ -156,6 +165,8 @@ var com = new function(){ var url_new; var url_cpart; var url_ppart; + var is_mbox_prev; + var is_mbox_curr; var url_upart; var url_dpart; @@ -211,7 +222,14 @@ var com = new function(){ url_cpart = that.url_curr.match(/toj\/(.*)/)[1].split('/'); url_cpart.pop(); - if(that.url_prev == null || (!check_mbox_url(that.url_prev) && check_mbox_url(that.url_curr))){ + if(that.url_prev == null){ + is_mbox_prev = false; + }else{ + is_mbox_prev = check_mbox_url(that.url_prev); + } + is_mbox_curr = check_mbox_url(that.url_curr); + + if(that.url_prev == null || (is_mbox_prev == false && is_mbox_curr == true)){ node_curr = that.vus_root; url_upart = new Array; url_dpart = url_cpart.slice(0); @@ -254,41 +272,48 @@ var com = new function(){ } } - if(that.url_prev == null || that.pbox_exist == false || !(check_mbox_url(that.url_prev) && !check_mbox_url(that.url_curr))){ + if(that.url_prev != null && is_mbox_prev == false && is_mbox_curr == false){ + index.page_scroll_reset(); + } + if(that.url_prev == null || that.pbox_exist == false || !(is_mbox_prev == true && is_mbox_curr == false)){ _chg_in(url_cpart,j,node_curr,url_upart,url_dpart); } - if(that.pbox_exist == false && !check_mbox_url(that.url_curr)){ + if(that.pbox_exist == false && is_mbox_curr == false){ that.pbox_exist = true; $('#index_mask').removeClass('index_mask_nopbox'); $('#index_mask').addClass('index_mask'); } } + arguments.callee.reentrant = false; }; that.exheight = function(){ - var i; - var es; - var extop; - var exbottom; - var j_e; - var j_parent; - - es = $('[exheight=true]'); - for(i = 0;i < es.length;i++){ - j_e = $(es[i]); - if((extop = j_e.attr('extop')) == undefined){ - extop = j_e.css('top').match(/(.+)px/)[1]; - } - if((exbottom = j_e.attr('exbottom')) == undefined){ - exbottom = 0; + var _ex = function(es,css){ + var i; + var extop; + var exbottom; + var j_e; + var j_parent; + + for(i = 0;i < es.length;i++){ + j_e = $(es[i]); + if((extop = j_e.attr('extop')) == undefined){ + extop = j_e.css('top').match(/(.+)px/)[1]; + } + if((exbottom = j_e.attr('exbottom')) == undefined){ + exbottom = 0; + } + extop = parseInt(extop); + exbottom = parseInt(exbottom); + + j_e.css(css,($(window).height() - (extop + exbottom) + 'px')); } - extop = parseInt(extop); - exbottom = parseInt(exbottom); + }; - j_e.css('height',($(window).height() - (extop + exbottom) + 'px')); - } + _ex($('[exheight=true]'),'height'); + _ex($('[exminheight=true]'),'min-height'); }; that.get_cookie = function(){ var ret; diff --git a/toj/jcs/home.css b/toj/jcs/home.css index e69de29..e69de29 100644..100755 --- a/toj/jcs/home.css +++ b/toj/jcs/home.css diff --git a/toj/jcs/home.js b/toj/jcs/home.js index 98c9683..d84d7ec 100644..100755 --- a/toj/jcs/home.js +++ b/toj/jcs/home.js @@ -18,7 +18,7 @@ var class_home_pbox = function(){ that.node.url_chg = function(direct,url_upart,url_dpart){ if(direct == 'in'){ that.fadein(j_pbox); - index.title_set('Taiwan Online Judge'); + index.title_set('Taiwan Online Judge (for sprout)'); tmp(); }else if(direct == 'out'){ that.fadeout(j_pbox); @@ -206,7 +206,7 @@ var class_home_pbox = function(){ drawCircle(ctx,700,500,70 + (prog % 24) * 4,bd * 360,0); ctx.font = 'bold 16px tahoma'; - drawTextAlongArc(ctx,"Hello TOJ",700,500,460,bd * 60,bd * (prog % 360 + 115) * 2); + drawTextAlongArc(ctx,"Hello TOJ [sprout]",700,500,460,bd * 60,bd * (prog % 360 + 115) * 2); drawTextAlongArc(ctx,"Are You Happy?",700,500,460,bd * 50,bd * (prog % 360 + 30) * 2); if(prog < 456 || prog > 912){ @@ -292,8 +292,8 @@ var class_home_pbox = function(){ ctx.font = 'bold 50px 微軟正黑體'; ctx.fillStyle = 'rgba(255,255,255,1)'; - ctx.fillText('Taiwan Online Judge システムテスト',1920 - (prog % 720) / 720 * 3000,980); - ctx.fillText('Taiwan Online Judge システムテスト',1920 - ((prog + 360) % 720) / 720 * 3000,980); + ctx.fillText('Taiwan Online Judge (for sprout) システムテスト',1920 - (prog % 720) / 720 * 3000,980); + ctx.fillText('Taiwan Online Judge (for sprout) システムテスト',1920 - ((prog + 360) % 720) / 720 * 3000,980); ctx.font = 'bold 36px 微軟正黑體'; u = ctx.measureText('Parallel Judge 使用可能').width + 64; @@ -368,7 +368,7 @@ var class_home_pbox = function(){ //ctx.fillStyle = 'rgba(128,0,0,' + u + ')'; //ctx.fillRect(960 - v / 2 - 10,380,v + 20,200); - //var canvas = document.createElement('xxxxx'); + //var canvas = document.createElement('sproutcanvas'); //var context = canvas.getContext('2d'); //var img = document.getElementById('myimg'); //context.drawImage(img, 0, 0 ); @@ -379,7 +379,7 @@ var class_home_pbox = function(){ var imageObjSprout = new Image(); - imageObjSprout.src = '/toj/jcs/xxxxx.png'; + imageObjSprout.src = '/toj/jcs/sprout2.png'; ctx.drawImage(imageObjSprout, 690,260,500,500); //var imgdSprout = ctx.getImageData(0, 0, 300, 300); //var Sproutpix_alpha = imgdSprout.data; diff --git a/toj/jcs/index.css b/toj/jcs/index.css index e784785..16da330 100644..100755 --- a/toj/jcs/index.css +++ b/toj/jcs/index.css @@ -8,7 +8,7 @@ div.index_head_box{ position:fixed; top:0px; left:0px; - z-index:1; + z-index:100; } div.index_head{ width:1224px; @@ -101,27 +101,24 @@ div.index_head_box > div.nickname > a:hover.nickname{ div.index_panel_box{ width:0px; - position:fixed; + background-color:#1C1C1C; + opacity:0; + position:absolute; left:auto; right:0px; top:32px; - overflow:hidden; - z-index:110; + overflow-x:hidden; + z-index:100; } ul.index_panel{ width:240px; - height:100%; margin:0px 0px; - padding:0px 0px; - background-color:#1C1C1C; - opacity:0; - position:absolute; + padding:0px 0px 64px 0px; + position:relative; left:auto; - right:-240px; + right:0px; top:0px; - z-index:2; overflow-x:hidden; - overflow-y:auto; list-style:none; } ul.index_panel > li.button{ @@ -184,7 +181,7 @@ div.index_mask{ position:absolute; top:0px; left:0px; - z-index:3; + z-index:1000; display:none; } div.index_mask_nopbox{ diff --git a/toj/jcs/index.js b/toj/jcs/index.js index 97c0c4b..102d067 100644..100755 --- a/toj/jcs/index.js +++ b/toj/jcs/index.js @@ -1,38 +1,42 @@ var index = new function(){ var that = this; + var page_scroll_ref = 0; + var page_scroll_top = 0; that.init = function(){ $(window).on('mouseover',function(e){ var j_panel; - if(e.target == null || e.target.id == 'index_panel' || $(e.target).parents('#index_panel').length > 0){ + if(e.target == null || e.target.id == 'index_panel_box' || $(e.target).parents('#index_panel_box').length > 0){ return; } j_panel = $('#index_head_panel'); if(e.target.id == 'index_head_panel'){ - $('#index_head_notice').removeClass('notice_s'); - $('#notice_list').stop().animate({opacity:0},'fast','easeOutQuad', - function(){ - $('#notice_list_box').css('width','0px'); - $('#notice_list').css('right','-240px'); - $('#notice_list a.item').css('left','50%'); - } - ); - - j_panel.addClass('panel_m'); - $('#index_panel_box').stop().animate({width:240},'slow','easeOutExpo'); - $('#index_panel').css('opacity','1').stop().animate({right:0},'slow','easeOutExpo'); - $('#index_panel a.button').stop().animate({left:0},'slow','easeOutQuart'); + + if($('#index_head_notice').hasClass('notice_s')){ + notice.hide(); + } + + if(!j_panel.hasClass('panel_m')){ + that.page_scroll_lock(); + + j_panel.addClass('panel_m'); + $('#index_panel_box').stop().css('opacity','1').animate({width:240},'slow','easeOutExpo'); + $('#index_panel a.button').stop().animate({left:0},'slow','easeOutQuart'); + } }else{ - $('#index_head_panel').removeClass('panel_m'); - $('#index_panel').stop().animate({opacity:0},'fast','easeOutQuad', - function(){ - $('#index_panel_box').css('width','0px'); - $('#index_panel').css('right','-240px'); - $('#index_panel a.button').css('left','50%'); - } - ); + if(j_panel.hasClass('panel_m')){ + j_panel.removeClass('panel_m'); + $('#index_panel_box').stop().animate({opacity:0},'fast','easeOutQuad', + function(){ + $('#index_panel_box').css('width','0px'); + $('#index_panel a.button').css('left','50%'); + + that.page_scroll_unlock(); + } + ); + } } }); $('#index_head_panel').on('mousedown',function(e){ @@ -124,19 +128,64 @@ var index = new function(){ $('#index_head > div.content_box').empty(); }; + that.page_scroll_lock = function(){ + var j_index; + + console.log('lock'); + if(page_scroll_ref == 0){ + j_index = $('#index_page'); + + page_scroll_top = $(window).scrollTop(); + off = -page_scroll_top + 32; + j_index.css('position','fixed'); + j_index.css('top',off + 'px'); + } + page_scroll_ref++; + }; + that.page_scroll_unlock = function(){ + var j_index; + + console.log('unlock'); + page_scroll_ref--; + if(page_scroll_ref == 0){ + j_index = $('#index_page'); + + j_index.css('position','absolute'); + j_index.css('top','32px'); + $(window).scrollTop(page_scroll_top); + } + }; + that.page_scroll_reset = function(){ + var j_index; + + console.log('reset'); + if(page_scroll_ref > 0){ + j_index = $('#index_page'); + if(j_index.css('position') == 'fixed'){ + page_scroll_top = 0; + j_index.css('top','32px'); + } + } + }; + that.mask_show = function(){ var j_mask; + var off; j_mask = $('#index_mask'); j_mask.stop().fadeIn('fast'); - if(j_mask.hasClass('index_mask')){ - $('#index_page').attr('exheight',true).css('overflow','hidden'); - com.exheight(); + that.page_scroll_lock(); } }; that.mask_hide = function(){ - $('#index_page').attr('exheight',false).css('height','auto').css('overflow','visible'); - $('#index_mask').stop().hide(); + var j_mask; + var j_index; + + j_mask = $('#index_mask'); + j_mask.stop().hide(); + if(j_mask.hasClass('index_mask')){ + that.page_scroll_unlock(); + } }; }; diff --git a/toj/jcs/notice.css b/toj/jcs/notice.css index 375bfef..2d9e8b8 100644..100755 --- a/toj/jcs/notice.css +++ b/toj/jcs/notice.css @@ -1,26 +1,23 @@ div.notice_list_box{ width:0px; - position:fixed; + background-color:#1C1C1C; + opacity:0; + position:absolute; left:auto; right:0px; top:32px; - overflow:hidden; - z-index:100; + overflow-x:hidden; + z-index:50; } ul.notice_list{ width:322px; - height:100%; margin:0px 0px; - padding:0px 0px; - background-color:#1C1C1C; - opacity:0; - position:absolute; + padding:0px 0px 64px 0px; + position:relative; left:auto; - right:-322px; + right:0px; top:0px; - z-index:2; overflow-x:hidden; - overflow-y:auto; list-style:none; } ul.notice_list > li.item{ diff --git a/toj/jcs/notice.js b/toj/jcs/notice.js index b2e5122..0f027fd 100644..100755 --- a/toj/jcs/notice.js +++ b/toj/jcs/notice.js @@ -6,6 +6,10 @@ var notice = new function(){ var listnew = function(noticeo){ j_item = $('<li class="item"><a class="item"><div class="head"></div><div class="content"></div></a></li>') j_a = j_item.find('a.item'); + j_a.on('click',function(e){ + that.hide(); + }); + j_head = j_item.find('div.head'); j_content = j_item.find('div.content'); @@ -105,7 +109,7 @@ var notice = new function(){ j_notice.removeClass('notice_h'); j_notice.text('[' + count + ']'); }else{ - if($('#notice_list').css('opacity') == 1){ + if($('#notice_list_box').css('opacity') == 1){ updatenew(); }else{ j_notice.addClass('notice_h'); @@ -123,32 +127,22 @@ var notice = new function(){ $(window).on('click',function(e){ var j_notice; - if(e.target == null || ($(e.target).parents('a.item').length == 0 && $(e.target).parents('#notice_list').length > 0)){ + if(e.target == null || ($(e.target).parents('a.item').length == 0 && $(e.target).parents('#notice_list_box').length > 0)){ return; } j_notice = $('#index_head_notice'); if(e.target.id == 'index_head_notice' && !j_notice.hasClass('notice_s')){ - j_notice.addClass('notice_s'); - $('#notice_list_box').stop().animate({width:322},'slow','easeOutExpo'); - $('#notice_list').css('opacity','1').stop().animate({right:0},'slow','easeOutExpo'); - $('#notice_list a.item').stop().animate({left:0},'slow','easeOutQuart'); - }else{ - j_notice.removeClass('notice_s'); - $('#notice_list').stop().animate({opacity:0},'fast','easeOutQuad', - function(){ - $('#notice_list_box').css('width','0px'); - $('#notice_list').css('right','-322px'); - $('#notice_list a.item').css('left','50%'); - } - ); + that.show(); + }else if(j_notice.hasClass('notice_s')){ + that.hide(); } }); $('#index_head_notice').on('click',function(e){ var j_list; j_list = $('#notice_list'); - if(j_list.css('opacity') == 0){ + if($('#notice_list_box').css('opacity') == 0){ j_list.empty(); enid = null; updatenew(); @@ -159,5 +153,22 @@ var notice = new function(){ refresh(); }; - + that.show = function(){ + index.page_scroll_lock(); + + $('#index_head_notice').addClass('notice_s'); + $('#notice_list_box').stop().css('opacity','1').animate({width:322},'slow','easeOutExpo'); + $('#notice_list a.item').stop().animate({left:0},'slow','easeOutQuart'); + }; + that.hide = function(){ + $('#index_head_notice').removeClass('notice_s'); + $('#notice_list_box').stop().animate({opacity:0},'fast','easeOutQuad', + function(){ + $('#notice_list_box').css('width','0px'); + $('#notice_list a.item').css('left','50%'); + + index.page_scroll_unlock(); + } + ); + }; }; diff --git a/toj/jcs/pro.css b/toj/jcs/pro.css index 0629ee1..0629ee1 100644..100755 --- a/toj/jcs/pro.css +++ b/toj/jcs/pro.css diff --git a/toj/jcs/pro.js b/toj/jcs/pro.js index ee28217..ee28217 100644..100755 --- a/toj/jcs/pro.js +++ b/toj/jcs/pro.js diff --git a/toj/jcs/sq.css b/toj/jcs/sq.css index e69de29..e69de29 100644..100755 --- a/toj/jcs/sq.css +++ b/toj/jcs/sq.css diff --git a/toj/jcs/sq.js b/toj/jcs/sq.js index 17c07c0..17c07c0 100644..100755 --- a/toj/jcs/sq.js +++ b/toj/jcs/sq.js diff --git a/toj/jcs/stat.css b/toj/jcs/stat.css index 607b922..6036a0f 100644..100755 --- a/toj/jcs/stat.css +++ b/toj/jcs/stat.css @@ -15,29 +15,12 @@ div.stat_page > div.sub_pbox > table.sublist tr:hover.item{ background-color:rgba(255,255,255,0.2); } div.stat_page > div.sub_pbox > table.sublist th,div.stat_page > div.sub_pbox > table.sublist td{ - padding:0px 0px 0px 6px; -} -div.stat_page > div.sub_pbox > table.sublist th.subid,div.stat_page > div.sub_pbox > table.sublist td.subid{ - width:76px; -} -div.stat_page > div.sub_pbox > table.sublist th.proid,div.stat_page > div.sub_pbox > table.sublist td.proid{ width:76px; + padding:0px 0px 0px 6px; } div.stat_page > div.sub_pbox > table.sublist th.nickname,div.stat_page > div.sub_pbox > table.sublist td.nickname{ width:auto; } -div.stat_page > div.sub_pbox > table.sublist th.runtime,div.stat_page > div.sub_pbox > table.sublist td.runtime{ - width:76px; -} -div.stat_page > div.sub_pbox > table.sublist th.memory,div.stat_page > div.sub_pbox > table.sublist td.memory{ - width:76px; -} -div.stat_page > div.sub_pbox > table.sublist th.result,div.stat_page > div.sub_pbox > table.sublist td.result{ - width:76px; -} -div.stat_page > div.sub_pbox > table.sublist th.score,div.stat_page > div.sub_pbox > table.sublist td.score{ - width:76px; -} div.stat_page > div.sub_pbox > table.sublist th.time,div.stat_page > div.sub_pbox > table.sublist td.time{ width:237px; } diff --git a/toj/jcs/stat.js b/toj/jcs/stat.js index 41a2796..41a2796 100644..100755 --- a/toj/jcs/stat.js +++ b/toj/jcs/stat.js diff --git a/toj/jcs/user.css b/toj/jcs/user.css index 71af8d7..d1c1b73 100644..100755 --- a/toj/jcs/user.css +++ b/toj/jcs/user.css @@ -34,13 +34,13 @@ div.user_page > div.edit_pbox > div.edit_box input{ display:block; } div.user_page > div.mgsq_pbox > div.in_box{ - width:480px; + width:486px; margin:0px 0px 0px 246px; padding:0px 0px 32px 0px; float:left; } div.user_page > div.mgsq_pbox > div.out_box{ - width:480px; + width:486px; margin:0px 0px 0px 6px; padding:0px 0px 32px 0px; float:left; @@ -65,7 +65,7 @@ div.user_page > div.mgsq_pbox div.item > div.info{ div.user_page > div.mgsq_pbox div.item > div.info > span.time{ width:237px; height:32px; - font-size:14px; + font-size:12px; line-height:32px; float:right; } @@ -80,6 +80,27 @@ div.user_page > div.mg_pbox > div.left_box{ padding:0px 0px 32px 0px; float:left; } +div.user_page > div.mg_pbox table.prolist{ + width:486px; + border-collapse:collapse; + text-align:left; +} +div.user_page > div.mg_pbox table.prolist tr.head{ + height:64px; +} +div.user_page > div.mg_pbox table.prolist tr.item{ + height:44px; +} +div.user_page > div.mg_pbox table.prolist tr:hover.item{ + background-color:rgba(255,255,255,0.2); +} +div.user_page > div.mg_pbox table.prolist th,div.user_page > div.mg_pbox table.prolist td{ + width:76px; + padding:0px 0px 0px 6px; +} +div.user_page > div.mg_pbox table.prolist th.name,div.user_page > div.mg_pbox table.prolist td.name{ + width:auto; +} div.user_mask > div.editsq_mbox > div.edit_box{ margin:0px 0px 0px 246px; @@ -97,6 +118,9 @@ div.user_mask > div.editsq_mbox > div.edit_box input{ border-width:0px; display:block; } +div.user_mask > div.editsq_mbox > div.edit_box > div.time > input{ + width:35px; +} div.user_mask > div.editsq_mbox > div.edit_box select{ width:76px; height:32px; @@ -105,6 +129,30 @@ div.user_mask > div.editsq_mbox > div.edit_box select{ display:block; } +div.user_mask > div.editpro_mbox > div.edit_box{ + margin:0px 0px 0px 246px; + padding:6px 0px 32px 0px; +} +div.user_mask > div.editpro_mbox > div.edit_box > div.error{ + margin:0px 0px 16px 0px; + color:#FFA0A0; +} +div.user_mask > div.editpro_mbox > div.edit_box input{ + width:146px; + height:32px; + margin:0px 0px 16px 0px; + padding:0px 6px 0px 6px; + border-width:0px; + display:block; +} +div.user_mask > div.editpro_mbox > div.edit_box select{ + width:76px; + height:32px; + margin:0px 0px 16px 0px; + border-width:0px; + display:block; +} + div.login_pbox > div.info_box{ width:486px; margin:128px 0px 0px 246px; diff --git a/toj/jcs/user.js b/toj/jcs/user.js index 9b36dbe..51859c1 100644..100755 --- a/toj/jcs/user.js +++ b/toj/jcs/user.js @@ -36,6 +36,7 @@ var user = new function(){ mgsq_pbox = new class_user_mgsq_pbox; mg_pbox = new class_user_mg_pbox; that.editsq_mbox = new class_user_editsq_mbox; + that.editpro_mbox = new class_user_editpro_mbox; that.user_node = new vus.node('user'); @@ -679,6 +680,56 @@ var class_user_mg_pbox = function(){ var that = this; var j_pbox = $('#index_page > div.user_page > div.mg_pbox'); + var pro_listset = function(j_item,proo){ + j_item.find('td.proid').text(proo.proid); + j_item.find('td.name').text(proo.proname); + j_item.find('td.cacheid').text(proo.cacheid); + }; + var pro_listnew = function(proo){ + var j_item; + + j_item = $('<tr class="item"><td class="proid"></td><td class="name"></td><td class="cacheid"></td><td><button class="setting" style="display:none;">設置</button></td></tr>'); + j_item.hover( + function(){ + $(this).find('button.setting').show(); + }, + function(){ + $(this).find('button.setting').hide(); + } + ); + j_item.find('button.setting').on('click',function(e){ + user.editpro_mbox.init('edit',proo).done(function(){ + pro_update(); + }); + com.url_push('/toj/m/user_editpro/'); + }); + + pro_listset(j_item,proo); + + return j_item; + }; + var pro_update = function(){ + $.post('/toj/php/problem.php',{'action':'get_pro_list','data':null},function(res){ + var i; + + var reto; + var j_table; + var j_item; + + if(res[0] == 'E'){ + return; + } + + reto = JSON.parse(res); + j_table = j_pbox.find('table.prolist'); + j_table.find('tr.item').remove(); + for(i = 0;i < reto.length;i++){ + j_item = pro_listnew(reto[i]); + j_table.append(j_item); + } + }); + }; + that.node = new vus.node('mg'); that.__super(); @@ -687,6 +738,8 @@ var class_user_mg_pbox = function(){ if(direct == 'in'){ index.tab_hl('mg'); that.fadein(j_pbox); + + pro_update(); }else if(direct == 'out'){ index.tab_ll('mg'); that.fadeout(j_pbox); @@ -699,6 +752,12 @@ var class_user_mg_pbox = function(){ user.editsq_mbox.init('new'); com.url_push('/toj/m/user_editsq/'); }); + j_pbox.find('button.newpro').on('click',function(e){ + user.editpro_mbox.init('new').done(function(){ + pro_update(); + }); + com.url_push('/toj/m/user_editpro/'); + }); }; __extend(class_user_mg_pbox,class_com_pbox); var class_user_editsq_mbox = function(){ @@ -886,6 +945,142 @@ var class_user_editsq_mbox = function(){ com.url_pull(); }); }; __extend(class_user_editsq_mbox,class_com_mbox); +var class_user_editpro_mbox = function(){ + var that = this; + var j_mbox = $('#index_mask > div.user_mask > div.editpro_mbox'); + var action; + var proid; + var defer; + + that.node = new vus.node('user_editpro'); + + that.__super(); + + that.init = function(act,proo){ + action = act; + if(action == 'edit'){ + proid = proo.proid; + + j_mbox.find('[name="proid"]').val(proo.proid); + j_mbox.find('[name="name"]').val(proo.proname); + j_mbox.find('[name="modid"]').val(proo.modid); + j_mbox.find('span.cacheid').text('當前CacheID:' + proo.cacheid); + if(proo.hidden == true){ + j_mbox.find('[name="hidden"]').val(2); + }else{ + j_mbox.find('[name="hidden"]').val(1); + } + j_mbox.find('div.update').show(); + j_mbox.find('button.delete').show(); + } + + com.vus_mbox.child_set(that.node); + + defer = $.Deferred(); + return defer.promise(); + }; + that.node.url_chg = function(direct,url_dpart,url_upart){ + if(direct == 'in'){ + that.fadein(j_mbox); + }else if(direct == 'out'){ + that.fadeout(j_mbox); + + j_mbox.find('input').val(''); + j_mbox.find('[name="hidden"]').val(1); + j_mbox.find('div.update').hide(); + j_mbox.find('button.delete').hide(); + j_mbox.find('div.error').text(''); + + if(defer.state() == 'pending'){ + defer.reject(); + } + + com.vus_mbox.child_del(that.node); + } + }; + + j_mbox.find('button.update').on('click',function(e){ + $.post('/toj/php/problem.php',{'action':'update_pro_cache','data':JSON.stringify({'proid':proid})},function(res){ + + defer.resolve(); + com.url_pull(); + }); + }); + j_mbox.find('button.submit').on('click',function(e){ + var proname; + var modid; + var hidden; + var j_error; + + proname = j_mbox.find('[name="name"]').val(); + modid = j_mbox.find('[name="modid"]').val(); + if(parseInt(j_mbox.find('[name="hidden"]').val()) == 1){ + hidden = false; + }else{ + hidden = true; + } + + j_error = j_mbox.find('div.error'); + if(action == 'new'){ + $.post('/toj/php/problem.php',{'action':'add_pro','data':JSON.stringify({'proname':proname,'modid':modid,'hidden':hidden})},function(res){ + if(res[0] == 'E'){ + switch(res){ + case 'Eno_login': + j_error.text('未登入'); + case 'Epermission_denied': + j_error.text('權限不足'); + break; + case 'Eproname_too_short': + j_error.text('題目名稱太短'); + break; + case 'Eproname_too_long': + j_error.text('題目名稱太長'); + break; + case 'Ewrong_modid': + j_error.text('模組ID錯誤'); + break; + default: + j_error.text('其他錯誤'); + break; + } + }else{ + defer.resolve(); + com.url_pull(); + } + }); + }else if(action == 'edit'){ + $.post('/toj/php/problem.php',{'action':'edit_pro','data':JSON.stringify({'proid':proid,'proname':proname,'modid':modid,'hidden':hidden})},function(res){ + if(res[0] == 'E'){ + switch(res){ + case 'Eno_login': + j_error.text('未登入'); + case 'Epermission_denied': + j_error.text('權限不足'); + break; + case 'Eproname_too_short': + j_error.text('題目名稱太短'); + break; + case 'Eproname_too_long': + j_error.text('題目名稱太長'); + break; + case 'Ewrong_modid': + j_error.text('模組ID錯誤'); + break; + default: + j_error.text('其他錯誤'); + break; + } + }else{ + defer.resolve(); + com.url_pull(); + } + }); + } + }); + j_mbox.find('button.cancel').on('click',function(e){ + com.url_pull(); + }); +}; __extend(class_user_editpro_mbox,class_com_mbox); var class_login_pbox = function(){ var that = this; diff --git a/toj/php/_json.php b/toj/php/_json.php new file mode 100755 index 0000000..b3c443e --- /dev/null +++ b/toj/php/_json.php @@ -0,0 +1,3 @@ +<?php +echo json_encode("#include <stdio.h>\nint main(){while(scanf(\"%d%d\", &a, &b)==2)printf(\"%d\n\", a+b); return 0;}\n"); +?> diff --git a/toj/php/_pzread_update.php b/toj/php/_pzread_update.php new file mode 100644 index 0000000..674f15b --- /dev/null +++ b/toj/php/_pzread_update.php @@ -0,0 +1,21 @@ +<?php +require_once('common.inc.php'); + +$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); +$sconn = socket_connect($socket, '127.0.0.1',CENTER_SOCKET_PORT); + +if(!$sconn) + exit('error'); + +$wret = socket_write($socket,'-1'.chr(0).'{}'.chr(0)); +if($wret === false) + exit('error'); + +$cret = socket_read($socket, 1024); +if($cret === false) + exit('error'); +if($cret[0] != 'S') + exit('error'); + +exit('ok'); +?> diff --git a/toj/php/_test.php b/toj/php/_test.php new file mode 100755 index 0000000..5ce8271 --- /dev/null +++ b/toj/php/_test.php @@ -0,0 +1,20 @@ +<form action="notice.php" method=post> + <input type='hidden' value='{"uid":111}' name='data'> + <input type='hidden' value='count' name='action'> + <input type='submit' value='ti jiao count'> +</form> +<form action="notice.php" method=post> + <input type='text' value='{"uid":111}' name='data'> + <input type='hidden' value='get' name='action'> + <input type='submit' value='ti jiao get'> +</form> +<form action="notice.php" method=post> + <input type='hidden' value='{"uid":111}' name='data'> + <input type='hidden' value='clear' name='action'> + <input type='submit' value='ti jiao clear'> +</form> +<form action="notice.php" method=post> + <input type='text' value='{"uid":111,"type":1,"value":111,"context":"aaaaaa"}' name='data'> + <input type='hidden' value='add' name='action'> + <input type='submit' value='ti jiao add'> +</form> diff --git a/toj/php/common.inc.php b/toj/php/common.inc.php index 0922c91..0922c91 100644..100755 --- a/toj/php/common.inc.php +++ b/toj/php/common.inc.php diff --git a/toj/php/connect.inc.php b/toj/php/connect.inc.php index 3eebe89..3eebe89 100644..100755 --- a/toj/php/connect.inc.php +++ b/toj/php/connect.inc.php diff --git a/toj/php/event.inc.php b/toj/php/event.inc.php index acc2f14..acc2f14 100644..100755 --- a/toj/php/event.inc.php +++ b/toj/php/event.inc.php diff --git a/toj/php/event.php b/toj/php/event.php index e121287..e121287 100644..100755 --- a/toj/php/event.php +++ b/toj/php/event.php diff --git a/toj/php/event_exec.cpp b/toj/php/event_exec.cpp index af258c0..af258c0 100644..100755 --- a/toj/php/event_exec.cpp +++ b/toj/php/event_exec.cpp diff --git a/toj/php/event_exec.h b/toj/php/event_exec.h index aec1acb..aec1acb 100644..100755 --- a/toj/php/event_exec.h +++ b/toj/php/event_exec.h diff --git a/toj/php/notice.inc.php b/toj/php/notice.inc.php index dbf47cc..dbf47cc 100644..100755 --- a/toj/php/notice.inc.php +++ b/toj/php/notice.inc.php diff --git a/toj/php/notice.php b/toj/php/notice.php index a0f984a..a0f984a 100644..100755 --- a/toj/php/notice.php +++ b/toj/php/notice.php diff --git a/toj/php/problem.inc.php b/toj/php/problem.inc.php index d6f8851..a7a717e 100644..100755 --- a/toj/php/problem.inc.php +++ b/toj/php/problem.inc.php @@ -133,8 +133,6 @@ class problem mkdir($pardir.$subid.'/result', 0755) or die('Ecannot_mkdir'); chmod($pardir.$subid.'/result', 0775) or die('Ecannot_chmod'); - //$file = fopen($pardir.$subid.'/data/'.$subid.'.'.$ext,'w'); - //20130205 tmp change $file = fopen($pardir.$subid.'/data/main.'.$ext,'w'); if(!$file) die('Ewrite_file_failed'); @@ -148,9 +146,15 @@ class problem { //Add a new problem $pro into problem table. //Return the inserted object. False if failed. + + if($pro->hidden == true){ + $hidden = 't'; + }else{ + $hidden = 'f'; + } $sqlstr = 'INSERT INTO "problem" ("modid", "proname", "hidden", "admin_uid") VALUES ($1, $2, $3, $4) RETURNING *;'; - $sqlarr = array($pro->modid, $pro->proname, $pro->hidden, $pro->admin_uid); + $sqlarr = array($pro->modid, $pro->proname, $hidden, $pro->admin_uid); $sqlr = pg_query_params($sqlstr, $sqlarr); if(!$sqlr) return false; @@ -161,7 +165,36 @@ class problem $obj->proid = intval($obj->proid); $obj->modid = intval($obj->modid); + $obj->cacheid = intval($obj->cacheid); $obj->admin_uid = intval($obj->admin_uid); + $obj->hidden = ($obj->hidden=='t'); + + return $obj; + } + + public static function edit($sqlc, $pro) + { + if($pro->hidden == true){ + $hidden = 't'; + }else{ + $hidden = 'f'; + } + + $sqlstr = 'UPDATE "problem" SET "modid"=$1, "proname"=$2, "hidden"=$3, "admin_uid"=$4 WHERE "proid"=$5 RETURNING *;'; + $sqlarr = array($pro->modid, $pro->proname, $hidden, $pro->admin_uid,$pro->proid); + $sqlr = pg_query_params($sqlstr, $sqlarr); + if(!$sqlr) + return false; + $obj = pg_fetch_object($sqlr, null, 'problem'); + pg_free_result($sqlr); + if(!$obj) + return false; + + $obj->proid = intval($obj->proid); + $obj->modid = intval($obj->modid); + $obj->cacheid = intval($obj->cacheid); + $obj->admin_uid = intval($obj->admin_uid); + $obj->hidden = ($obj->hidden=='t'); return $obj; } @@ -194,7 +227,7 @@ class problem return intval($ret); } - public static function send_socket($subid, $proid) + public static function send_socket($subid) { ///send socket to center. //Return true if success, false if failed. @@ -248,6 +281,36 @@ class problem return $ret; } + public static function get_pro_list($sqlc){ + $sqlstr = 'SELECT * FROM "problem" ORDER BY "proid" ASC;'; + $sqlr = pg_query($sqlc,$sqlstr); + + $ret = array(); + while($obj = pg_fetch_object($sqlr)) + { + $obj->proid = intval($obj->proid); + $obj->modid = intval($obj->modid); + $obj->cacheid = intval($obj->cacheid); + $obj->admin_uid = intval($obj->admin_uid); + $obj->hidden = ($obj->hidden=='t'); + array_push($ret, $obj); + } + + pg_free_result($sqlr); + return $ret; + } + + public static function update_pro_cache($sqlc,$proid){ + $sqlstr = 'UPDATE "problem" SET "cacheid"="cacheid" + 1 WHERE "proid"=$1;'; + $sqlarr = array($proid); + $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr); + if(!$sqlr)return false; + pg_free_result($sqlr); + + if(!problem::send_socket(-1))return false; + else return true; + } + public static function rejudge_pro($sqlc, $proid) { $sqlstr = 'SELECT "subid" FROM "submit" WHERE "proid"=$1 ORDER BY "subid";'; @@ -259,7 +322,7 @@ class problem foreach($sublist as $sub) { $subid = intval($sub); - if(!problem::send_socket($subid, $proid))$ok = false; + if(!problem::send_socket($subid))$ok = false; } return $ok; } @@ -272,7 +335,7 @@ class problem $proid = intval(pg_fetch_result($res, 0)); if(!$proid)return false; - return problem::send_socket($subid, $proid); + return problem::send_socket($subid); } } diff --git a/toj/php/problem.php b/toj/php/problem.php index 0bca821..1d6a2ba 100644..100755 --- a/toj/php/problem.php +++ b/toj/php/problem.php @@ -1,6 +1,6 @@ <?php -ini_set("display_errors", "On"); -error_reporting(E_ALL & ~E_NOTICE); +//ini_set("display_errors", "On"); +//error_reporting(E_ALL & ~E_NOTICE); require_once('problem.inc.php'); require_once('user.inc.php'); @@ -54,7 +54,7 @@ if($action == 'add_pro') if(!problem::getmod($sqlc, $dt->modid)) die('Ewrong_modid'); - if($dt->hidden != 't' && $dt->hidden != 'f') + if($dt->hidden !== true && $dt->hidden !== false) die('Ewrong_hidden_value'); /*CHECK OTHER DATA, TESTDATA ETC*/ @@ -67,6 +67,39 @@ if($action == 'add_pro') echo(json_encode($pro)); } +if($action == 'edit_pro') +{ + //Edit problem + //need SUPERADMIN + //data: modid, proname, [hidden] + if(!sec_is_login()) + die('Enot_login'); + if(!sec_check_level($sqlc, USER_PER_PROCREATOR)) + die('Epermission_denied'); + + $dt = json_decode($data); + + if(strlen($dt->proname) == 0) + die('Eproname_too_short'); + if(strlen($dt->proname) > PRONAME_LEN_MAX) + die('Eproname_too_long'); + + if(!problem::getmod($sqlc, $dt->modid)) + die('Ewrong_modid'); + + if($dt->hidden !== true && $dt->hidden !== false) + die('Ewrong_hidden_value'); + + /*CHECK OTHER DATA, TESTDATA ETC*/ + + $dt->admin_uid = intval($_COOKIE['uid']); + + $pro = problem::edit($sqlc, $dt); + if(!$pro) + die('Eedit_problem'); + + echo(json_encode($pro)); +} if($action == 'submit_code') { //Submit code @@ -133,6 +166,34 @@ if($action == 'get_pro_stat') echo(json_encode($ret)); } +if($action == 'get_pro_list') +{ + if(!sec_is_login()) + die('Enot_login'); + if(!sec_check_level($sqlc, USER_LEVEL_SUPERADMIN)) + die('Epermission_denied'); + + $ret = problem::get_pro_list($sqlc); + if(!$ret) + die('Error_get_pro_list'); + + echo(json_encode($ret)); +} +if($action == 'update_pro_cache') +{ + if(!sec_is_login()) + die('Enot_login'); + if(!sec_check_level($sqlc, USER_PER_PROCREATOR)) + die('Epermission_denied'); + + $dt = json_decode($data); + + $proid = intval($dt->proid); + if(!problem::update_pro_cache($sqlc,$proid)) + die('Eupdate_problem_cache'); + + echo('S'); +} db_close($sqlc); diff --git a/toj/php/pzreadtest.php b/toj/php/pzreadtest.php index b67ae9e..b67ae9e 100644..100755 --- a/toj/php/pzreadtest.php +++ b/toj/php/pzreadtest.php diff --git a/toj/php/sqlib.inc.php b/toj/php/sqlib.inc.php index 154bcbd..154bcbd 100644..100755 --- a/toj/php/sqlib.inc.php +++ b/toj/php/sqlib.inc.php diff --git a/toj/php/sqlib_scoreboard.inc.php b/toj/php/sqlib_scoreboard.inc.php index e5e7d66..e5e7d66 100644..100755 --- a/toj/php/sqlib_scoreboard.inc.php +++ b/toj/php/sqlib_scoreboard.inc.php diff --git a/toj/php/square.inc.php b/toj/php/square.inc.php index 784490d..784490d 100644..100755 --- a/toj/php/square.inc.php +++ b/toj/php/square.inc.php diff --git a/toj/php/square.php b/toj/php/square.php index ca57994..ca57994 100644..100755 --- a/toj/php/square.php +++ b/toj/php/square.php diff --git a/toj/php/status.inc.php b/toj/php/status.inc.php index 33765b0..33765b0 100644..100755 --- a/toj/php/status.inc.php +++ b/toj/php/status.inc.php diff --git a/toj/php/status.php b/toj/php/status.php index 8f0074f..8f0074f 100644..100755 --- a/toj/php/status.php +++ b/toj/php/status.php diff --git a/toj/php/step.inc.php b/toj/php/step.inc.php new file mode 100755 index 0000000..a116a64 --- /dev/null +++ b/toj/php/step.inc.php @@ -0,0 +1,17 @@ +<?php + +require_once('common.inc.php'); +require_once('square.inc.php'); +require_once('sqlib_scoreboard.inc.php'); + +function get_prob_stat_uid($sqlc, $msqlc, $sqid, $sboard_id, $uid) +{ + $sq = square::get($sqlc, $sqid); + if(!$sq)die('Eno_such_sq'); + + $data = sqlib_scoreboard::get_scoreboard_uid($sqlc, $msqlc, $sqid, $sboard_id, null, $sq->start_time, $sq->end_time, $uid); + + return $data[0]; +} + +?> diff --git a/toj/php/step.php b/toj/php/step.php new file mode 100755 index 0000000..6425ae1 --- /dev/null +++ b/toj/php/step.php @@ -0,0 +1,64 @@ +<?php +//ini_set("display_errors", "On"); + +require_once('common.inc.php'); +require_once('step.inc.php'); +require_once('teamt.php'); + +$sqlc = db_connect(); +$msqlc = db_connect('toj_mod'); + +if(strlen($action)==0) + die('Eno_action'); +if($action == '') +{ +} + +$uid = $_GET['uid']; +$dat = get_prob_stat_uid($sqlc, $msqlc, 1, 2, $uid); + +//var_dump($dat); +echo('uid : '.$dat->uid.'<br>'); +foreach($dat->problem as $prob) +{ + echo('problem '.$prob->proid.' : '); + if(!$prob->tries) + { + echo('--<br>'); + continue; + } + echo($prob->best_score.' '); + if($prob->is_ac)echo('AC'); + echo('<br>'); +} + +$term = 1; +$teamid = get_teamid($msqlc, $term, $uid); +echo('<br>Team : '.$teamid.'<br>Members : <br>'); +$members = get_team_member($msqlc, $term, $teamid); +foreach($members as $mem) +{ + echo('<br>Uid : '.$mem->uid.' ( Level '.$mem->level.' )<br>'); + $uid = intval($mem->uid); + if($uid == intval($_GET['uid']))continue; + $dat = get_prob_stat_uid($sqlc, $msqlc, 1, 2, $uid); + + foreach($dat->problem as $prob) + { + echo('problem '.$prob->proid.' : '); + if(!$prob->tries) + { + echo('--<br>'); + continue; + } + echo($prob->best_score.' '); + if($prob->is_ac)echo('AC'); + echo('<br>'); + } +} + + +db_close($sqlc); +db_close($msqlc); + +?> diff --git a/toj/php/teamt.php b/toj/php/teamt.php new file mode 100755 index 0000000..13c7bad --- /dev/null +++ b/toj/php/teamt.php @@ -0,0 +1,28 @@ +<?php +// +require_once('common.inc.php'); + +function get_teamid($msqlc, $term, $uid) +{ + $sqlstr = 'SELECT "teamid" FROM "sqmod_sprout_team" WHERE "term"=$1 AND "uid"=$2;'; + $sqlarr = array($term, $uid); + $res = pg_query_params($sqlstr, $sqlarr); + $teamid = pg_fetch_result($res, 0); + return $teamid; +} + +function get_team_member($msqlc, $term, $teamid) +{ + $sqlstr = 'SELECT "uid", "level" FROM "sqmod_sprout_team" WHERE "term"=$1 AND "teamid"=$2 ORDER BY "level" DESC, "uid";'; + $sqlarr = array($term, $teamid); + $res = pg_query_params($sqlstr, $sqlarr); + $ret = array(); + while($obj = pg_fetch_object($res)) + { + array_push($ret, $obj); + } + return $ret; +} + + +?> diff --git a/toj/php/test.php b/toj/php/test.php new file mode 100755 index 0000000..4d39e6e --- /dev/null +++ b/toj/php/test.php @@ -0,0 +1,93 @@ +<?php +ini_set("display_errors", "On"); +error_reporting(E_ALL & ~E_NOTICE); + +require_once('common.inc.php'); +require_once('sqlib.inc.php'); +require_once('user.inc.php'); +require_once('problem.inc.php'); + +$msqlc = db_connect('toj_mod'); +$sqlc = db_connect(); + +function func($sqid, $proid, $best_score, $best_time, $is_ac, $ac_time, $tries_before_ac, $last_score, $last_status, $last_time, $tries) +{ + return $best_score; +} + +//$a = intval($_GET['a']); +//sqlib_scoreboard::set_last_update($msqlc, 1, 4, false); +//$scb = sqlib_scoreboard::get_scoreboard($sqlc, $msqlc, 1, $a, func, null, null, 1, 20); +//var_dump($scb); +//echo(json_encode($scb)); +//$test = sqlib_scoreboard::get_last_update($msqlc, 1, $a); +//echo($test.'<br>'); +//echo(strtotime($test).'<br>'); +//echo(time()); + +/*for($i = 5; $i <= 61; $i++){ +echo('uid : '.$i.'<br>'); +$res = user::reset_password($sqlc, $i); +var_dump($res); +}*/ +//user::reset_password($sqlc, 16); + +if(!sec_check_level($sqlc, USER_LEVEL_SUPERADMIN)) + die('Epermission_denied'); + +if($_GET['code']=='code') +{ + $subid = intval($_GET['subid']); + if(!$subid) + die('Eno_subid'); + $path = '../center/submit/'.(int)(floor($subid/1000)*1000).'/'.$subid.'/data/main.cpp'; + $code = file_get_contents($path); + if(!$code) + die('Eerror_get_code'); + + $sarr = array('<', '>'); + $darr = array('<', '>'); + + $ncode = str_replace($sarr, $darr, $code); + + echo('Subid: '.$subid.'<br>'); +?> +<script type="text/javascript" src="http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js"></script> +<script type="text/javascript" src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCpp.js"></script> +<link href="http://alexgorbatchev.com/pub/sh/current/styles/shCore.css" rel="stylesheet" type="text/css" /> +<link href="http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css" rel="stylesheet" type="text/css" /> +<?php + echo('<pre class="brush: cpp">'); + echo($ncode); + echo('</pre>'); +?> +<script type="text/javascript"> + SyntaxHighlighter.all() +</script> +<?php +} +//exit(); +if($_GET['rejudge']=='sub') +{ + $subid = intval($_GET['subid']); + if(!$subid) + die('Eno_subid'); + $res = problem::rejudge_sub($sqlc, $subid); + if(!$res) + die('Eerror_rejudge'); + echo('S'); +} +if($_GET['rejudge']=='pro') +{ + $proid = intval($_GET['proid']); + if(!$proid) + die('Eno_proid'); + $res = problem::rejudge_pro($sqlc, $proid); + if(!$res) + die('Eerror_rejudge'); + echo('S'); +} + +db_close($sqlc); +db_close($msqlc); +?> diff --git a/toj/php/user.inc.php b/toj/php/user.inc.php index 8b3bb61..8b3bb61 100644..100755 --- a/toj/php/user.inc.php +++ b/toj/php/user.inc.php diff --git a/toj/php/user.php b/toj/php/user.php index 4570700..4570700 100644..100755 --- a/toj/php/user.php +++ b/toj/php/user.php |