Beispiel #1
0
/*
 * take ressources because pthread_cancel do not free the memory allocation
 * but we have to cancel the thread because we can stay in accept wait event if we try to use a non blocked socket
 */
void *minstack_tcp_accept_thread(void *ptr) {
    minstack_tcp *mt = (minstack_tcp *) ptr;
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

    printdebug("starting %s\n",__FUNCTION__);
    while (!mt->pthread_accept_thread_stop) {
        int tmp_clisockfd;
        unsigned int cli_len;
        struct sockaddr_in cli_addr;

        memset((char *) &cli_addr, 0, sizeof(cli_addr));
        cli_len = sizeof(cli_addr);
#ifdef WIN32
        tmp_clisockfd = accept(mt->listen_socket_fd, (struct sockaddr *) &cli_addr,(int *) &cli_len);
#else
        tmp_clisockfd = accept(mt->listen_socket_fd, (struct sockaddr *) &cli_addr, &cli_len);
#endif
        if (tmp_clisockfd == -1) {
            usleep(mt->receive_loop_usleep);
            continue;
        } else if (tmp_clisockfd <= 0) {
            printerror("error :%d\n",tmp_clisockfd);
            printmoreerror("ERROR on accept:");
            break;
        }
        pthread_mutex_lock(&mt->mutex);
        mt->sockets.client_socket_fd[mt->sockets.connected_client_nb]
                = tmp_clisockfd;
        mt->sockets.connected_client_nb++;
        pthread_mutex_unlock(&mt->mutex);
        mt->new_connection_callback(tmp_clisockfd, &cli_addr);
        if (mt->pthread_reading_thread_stop && pthread_create(
                &mt->pthread_reading_thread, NULL, minstack_tcp_reading_thread,
                (void *) mt)) {
            printwarning("pthread_create minstack_tcp_accept_thread error\n");
            continue;
        }
    }
    //TODO what is this ?!!!
    //before was //if (mt->pthread_reading_thread && !mt->pthread_reading_thread) {
    if (&mt->pthread_reading_thread && !mt->pthread_reading_thread_stop){
        mt->pthread_reading_thread_stop = 1;
        pthread_join(mt->pthread_reading_thread, NULL);
        printmessage("The reading thread stopped\n");
    }
    printdebug("stopping %s\n",__FUNCTION__);
    pthread_exit(NULL);
    return NULL;
}
Beispiel #2
0
/**
 * \brief Stop the minstack_tcp in parameter
 * \param mt the minstack_tcp that have to be stopped
 * \return 0 if the minstack_tcp stack stopped correctly
 */
int minstack_tcp_stop(minstack_tcp *mt) {
    if (!mt || mt->status == IDLE) {
        printerror("Cannot stop while not started\n");
        return -1;
    }
#ifdef NOT_CANCEL_THREAD_WHEN_STOPPING
    if (&mt->pthread_accept_thread && !mt->pthread_accept_thread_stop) {
        printdebug("The accepting thread is asked to stop\n");
        mt->pthread_accept_thread_stop = 1;
        pthread_join(mt->pthread_accept_thread, NULL);
        printmessage("The accepting thread stopped\n");
    }
    if (&mt->pthread_reading_thread && !mt->pthread_reading_thread_stop) {
        printdebug("The reading thread is asked to stop\n");
        mt->pthread_reading_thread_stop = 1;
        pthread_join(mt->pthread_reading_thread, NULL);
        printmessage("The reading thread stopped\n");
    }
#else
    if (&mt->pthread_accept_thread && !mt->pthread_accept_thread_stop) {
            printdebug("The accepting thread is asked to stop\n");
            mt->pthread_accept_thread_stop = 1;
            //Check if & or not after
            if(&mt->pthread_accept_thread)
                pthread_cancel(mt->pthread_accept_thread);
            printmessage("The accepting thread stopped\n");
        }
        if (&mt->pthread_reading_thread && !mt->pthread_reading_thread_stop) {
            printdebug("The reading thread is asked to stop\n");
            mt->pthread_reading_thread_stop = 1;
            //Check if & or not after
            if(&mt->pthread_reading_thread)
                pthread_cancel(mt->pthread_reading_thread);
            printmessage("The reading thread stopped\n");
        }
#endif
    if (mt->listen_socket_fd)
        minstack_close(mt->listen_socket_fd);
    pthread_mutex_destroy(&mt->mutex);
    mt->status = IDLE;
    printmessage("%s is now stopped\n",mt->name);
    return 0;
}
Beispiel #3
0
int minstack_tcp_delete_cid(sockets *mt, int cid) {
    int i;
    for (i = 0; i < mt->connected_client_nb; i++) {
        printdebug("%s socket:%d\n",__FUNCTION__,cid);
        if (mt->client_socket_fd[i] == cid) {
            //we have found the cid
            for (; i < (mt->connected_client_nb - 1); i++) {
                mt->client_socket_fd[i] = mt->client_socket_fd[i + 1];
            }
            mt->connected_client_nb--;
            return 0;
        }
    }
    return -1;
}
Beispiel #4
0
/**
 * \brief Uninitialized a minstack_tcp
 * \param mt is the minstack_tcp stack
 */
void minstack_tcp_uninit(minstack_tcp *mt) {
    if (!mt) {
        printwarning("Trying to uninit a NULL minstack_tcp\n");
        return;
    }
    if (mt->status == STARTED) {
        minstack_tcp_stop(mt);
        printdebug("%s minstack has TCP been stopped before uninit\n",mt->name);
    }
    printmessage("%s minstack TCP has been uninitialized\n",mt->name);
    free(mt);
#ifdef WIN32
    win32_uninit_socket_api();
#endif
}
Beispiel #5
0
/**
 * \brief Boot the minstack_tcp in client mode
 * \param mt the minstack_tcp that have to be boot
 * \return 0 if the minstack_tcp stack boot correctly
 */
int minstack_tcp_boot_client(minstack_tcp *mt) {
    struct sockaddr_in serv_addr;
    struct hostent *server;
    if (!mt)
        return -1;

    mt->listen_socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (mt->listen_socket_fd < 0) {
        printmoreerror("ERROR opening socket:");
        return -2;
    }
    server = gethostbyname(mt->address);
    if (server == NULL) {
        fprintf(stderr, "ERROR, no such host :%s\n",mt->address);
        return -3;
    }
    memset((char *) &serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
#ifndef WIN32
    bcopy((char *) server->h_addr, (char *) &serv_addr.sin_addr.s_addr,
            server->h_length);
#else
    memcpy( (char *) &serv_addr.sin_addr.s_addr,(char *) server->h_addr,
            server->h_length);
#endif
    serv_addr.sin_port = htons(mt->port);
    if (connect(mt->listen_socket_fd, (const struct sockaddr *) &serv_addr,
            (socklen_t) sizeof(serv_addr)) < 0) {
        printmoreerror("ERROR connecting:");
        return -4;
    }
    if (mt->external_read_socket == NULL) {
        printdebug("We do not start the reading thread in client mode because no external interpretation is done\n");
        mt->pthread_accept_thread_stop = 1;
        mt->pthread_reading_thread_stop = 1;
        return 0;
    }
    mt->sockets.client_socket_fd[0] = mt->listen_socket_fd;
    mt->sockets.connected_client_nb = 1;
    mt->pthread_accept_thread_stop = 1;//because it will not run
    if (pthread_create(&mt->pthread_reading_thread, NULL,
            minstack_tcp_reading_thread, (void *) mt)) {
        printwarning("pthread_create minstack_tcp_accept_thread error\n");
        return -5;
    }
    return 0;
}
Beispiel #6
0
/**
 * \brief Boot the minstack_tcp in server mode
 * \param mt the minstack_tcp that have to be boot
 * \return 0 if the minstack_tcp stack boot correctly
 */
int minstack_tcp_boot_server(minstack_tcp *mt) {
    struct sockaddr_in serv_addr;

    if (!mt)
        return -1;
    pthread_mutex_lock(&mt->mutex);
    mt->listen_socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (mt->listen_socket_fd < 0) {
        printmoreerror("ERROR opening socket:");
        return -2;
    }
#ifndef WIN32
    if (fcntl(mt->listen_socket_fd, F_SETFL, O_NONBLOCK) < 0) {
        printmoreerror("Could not O_NONBLOCK:");
        return -3;
    }
#else
    {
        u_long imode = 1;
        if(ioctlsocket(mt->listen_socket_fd,FIONBIO,&imode)  < 0) {
            printmoreerror("Could not O_NONBLOCK:");
            return -3;
        }
    }
#endif
    memset((char *) &serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(mt->port);
    if (bind(mt->listen_socket_fd, (const struct sockaddr *) &serv_addr,
            (socklen_t) sizeof(serv_addr)) < 0) {
        printmoreerror("ERROR connecting");
        pthread_mutex_unlock(&mt->mutex);
        return -4;
    }
    listen(mt->listen_socket_fd, (int) mt->max_client_nb);
    if (pthread_create(&mt->pthread_accept_thread, NULL, minstack_tcp_accept_thread, mt)) {
        printwarning("pthread_create minstack_tcp_boot_server error\n");
        pthread_mutex_unlock(&mt->mutex);
        return -5;
    }
    pthread_mutex_unlock(&mt->mutex);
    printdebug("%s started.\n",__FUNCTION__);
    return 0;
}
Beispiel #7
0
char *minstack_tcp_default_read(int cid, unsigned int *buffer_size_returned) {
    int retval, finished = 0;
    char read_buffer[DEFAULT_READ_BUFFER_SIZE] = { 0 };
    unsigned int buffer_size = DEFAULT_READ_BUFFER_SIZE;
    char *buffer;

    printdebug("There is something that is going to be read\n");
    if (!buffer_size_returned) {
        printerror("You have to give a pointer to buffer_size_returned\n");
        return NULL;
    }
    buffer = (char *) calloc(1, buffer_size);

    if (!buffer) {
        printerror("We could not get enough memory to allocate %d octets to read\n",sizeof(read_buffer));
        *buffer_size_returned = 0;
        return NULL;
    }

    while (!finished) {
        //retval = read(cid,read_buffer,DEFAULT_READ_BUFFER_SIZE);
        retval = recv(cid, read_buffer, DEFAULT_READ_BUFFER_SIZE, MSG_DONTWAIT);
        printdebug("recv returned %d\n",retval);
        if (retval > 0 && retval < DEFAULT_READ_BUFFER_SIZE) {
            memcpy(buffer + (buffer_size - DEFAULT_READ_BUFFER_SIZE),
                    read_buffer, DEFAULT_READ_BUFFER_SIZE);
            finished = 1;
        } else if (retval == DEFAULT_READ_BUFFER_SIZE) {
            char *new_buffer;
            memcpy(buffer + (buffer_size - DEFAULT_READ_BUFFER_SIZE),
                    read_buffer, DEFAULT_READ_BUFFER_SIZE);
            new_buffer = (char *) calloc(1, buffer_size
                    +DEFAULT_READ_BUFFER_SIZE);
            if (!new_buffer) {
                printmoreerror("we had a problem to read when moving buffers");
                free(buffer);
                *buffer_size_returned = 0;
                return NULL;
            }
            /*
             new_buffer = strncpy(new_buffer,buffer,buffer_size);
             char *p_next_char = new_buffer + buffer_size;
             strncpy(p_next_char,read_buffer,DEFAULT_READ_BUFFER_SIZE);
             */
            memcpy(new_buffer, buffer, buffer_size);
            buffer_size += DEFAULT_READ_BUFFER_SIZE;
            free(buffer);
            buffer = new_buffer;
            finished = 0;
        } else if (retval < 0) {
            //printmoreerror("we had a problem to read");
            printdebug("we had a problem to read\n");
            free(buffer);
            *buffer_size_returned = 0;
            return NULL;
        } else if (retval == 0) {
            //the client just disconnected
            if (buffer)
                free(buffer);
            *buffer_size_returned = -1;
            return NULL;
        }
    }
    *buffer_size_returned = buffer_size;
    return buffer;
}
Beispiel #8
0
void *minstack_tcp_reading_thread(void *ptr) {
    minstack_tcp *mt = (minstack_tcp *) ptr;
    fd_set fds_read;
    int fdmax;
    struct timeval tv;

    printdebug("starting %s\n",__FUNCTION__);
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

    mt->pthread_reading_thread_stop = 0;
    while (!mt->pthread_reading_thread_stop) {
        int i, retval, socket_to_read = -1;
        fdmax = 0;
        tv.tv_sec = 0;
        tv.tv_usec = (mt->receive_loop_usleep);
        FD_ZERO(&fds_read);
        pthread_mutex_lock(&mt->mutex);
        if (mt->sockets.connected_client_nb == 0) {
            pthread_mutex_unlock(&mt->mutex);
            usleep(mt->receive_loop_usleep);
            //printdebug("there is no client\n");
#ifdef	STOP_READING_THREAD_WITHOUT_CLIENTS
            break;
#else
            continue;
#endif
        }
        for (i = 0; i < mt->sockets.connected_client_nb; i++) {
            printdebug("Stay socket %d\n",mt->sockets.client_socket_fd[i]);
            FD_SETMAX(mt->sockets.client_socket_fd[i],&fds_read,fdmax);
        }
        fdmax++;
        pthread_mutex_unlock(&mt->mutex);

        retval = select(fdmax, &fds_read, NULL, NULL, &tv);
        pthread_mutex_lock(&mt->mutex);
        if (retval == EBADF) {
            printmoreerror("Select Bad FD\n");
            continue;
        }
        if (retval < 0) {
            printerror("Select: got an error %d\n",retval);
            printmoreerror("Select:");
            break;
        }
        if (retval) {
            printdebug("there is something to read\n");
            for (i = 0; i < mt->sockets.connected_client_nb; i++) {
                if (FD_ISSET(mt->sockets.client_socket_fd[i],&fds_read)) {
                    socket_to_read = mt->sockets.client_socket_fd[i];
                }
            }
        }
        if (!retval) {
            //printmoreerror("Nothing much from the select\n");
        }
        pthread_mutex_unlock(&mt->mutex);
        if (socket_to_read > 0) {
        	char from[16];
            char *buffer=NULL;
            int buffer_size = 0;
            pthread_mutex_lock(&mt->mutex);
            pthread_mutex_unlock(&mt->mutex);
            buffer_size = mt->read_socket(socket_to_read, from,&buffer);

            if (buffer_size <= 0) {
                pthread_mutex_lock(&mt->mutex);
                if (mt && mt->connection_closed_callback
                        && (mt->type == SERVER)) {
                    mt->connection_closed_callback(&mt->sockets, socket_to_read);
                    minstack_close(socket_to_read);
                    printdebug("Closing the socket %d\n",socket_to_read);
                }
                pthread_mutex_unlock(&mt->mutex);
                if (mt && (mt->type == CLIENT)) {
                    printmessage("The server do not exists anymore we will close the connection\n");
                    minstack_close(socket_to_read);
                    minstack_tcp_stop(mt);
                }
            } else {
                printmessage("%s received from %s(%d):(%u)=>%s\n",mt->name,from, socket_to_read,buffer_size,buffer);
                if (mt->external_read_socket)
                    mt->external_read_socket(socket_to_read, from, buffer, buffer_size);
                //else
                free(buffer);
            }
        }

    }
    mt->pthread_reading_thread_stop = 1;
    printdebug("stopping %s\n",__FUNCTION__);
    pthread_exit(NULL);
    return NULL;
}
Beispiel #9
0
int minstack_tcp_recvfrom_read(int cid, char *from, char **buffer) {
	int buffer_size_returned=0;
    int retval, finished = 0;
    char read_buffer[DEFAULT_READ_BUFFER_SIZE] = { 0 };
    unsigned int buffer_size = DEFAULT_READ_BUFFER_SIZE;
    struct sockaddr_storage their_addr;
    socklen_t addr_len;

    printdebug("There is something that is going to be read\n");
    if (*buffer != NULL) {
    	printerror("You have to give a NULL pointer for buffer\n");
    	return -1;
    }
    if (from == NULL) {
        printerror("You have to give a char tab for from\n");
        return -2;
    }
    *buffer = (char *) calloc(1, buffer_size);
    if (!*buffer) {
        printerror("We could not get enough memory to allocate %d octets to read\n",sizeof(read_buffer));
        buffer_size_returned = 0;
        return -4;
    }

    while (!finished) {
    	int ret_getpeername=0;
        //retval = read(cid,read_buffer,DEFAULT_READ_BUFFER_SIZE);
        retval = recv(cid, read_buffer, DEFAULT_READ_BUFFER_SIZE, MSG_DONTWAIT);
        printdebug("recv returned %d\n",retval);
        addr_len = sizeof(their_addr);
        ret_getpeername = getpeername(cid, (struct sockaddr *)&their_addr, &addr_len);
        printdebug("getpeername returned %d:%s\n",ret_getpeername,strerror(errno));
        if (retval > 0 && retval < DEFAULT_READ_BUFFER_SIZE) {
            memcpy(*buffer + (buffer_size - DEFAULT_READ_BUFFER_SIZE),
                    read_buffer, DEFAULT_READ_BUFFER_SIZE);
            finished = 1;
        } else if (retval == DEFAULT_READ_BUFFER_SIZE) {
            char *new_buffer;
            memcpy(*buffer + (buffer_size - DEFAULT_READ_BUFFER_SIZE),
                    read_buffer, DEFAULT_READ_BUFFER_SIZE);
            new_buffer = (char *) calloc(1, buffer_size
                    +DEFAULT_READ_BUFFER_SIZE);
            if (!new_buffer) {
                printmoreerror("we had a problem to read when moving buffers");
                free(*buffer);
                buffer_size_returned = 0;
                return -5;
            }
            /*
             new_buffer = strncpy(new_buffer,buffer,buffer_size);
             char *p_next_char = new_buffer + buffer_size;
             strncpy(p_next_char,read_buffer,DEFAULT_READ_BUFFER_SIZE);
             */
            memcpy(new_buffer, *buffer, buffer_size);
            buffer_size += DEFAULT_READ_BUFFER_SIZE;
            free(*buffer);
            *buffer = new_buffer;
            finished = 0;
        } else if (retval < 0) {
            //printmoreerror("we had a problem to read");
            printdebug("we had a problem to read\n");
            free(*buffer);
            buffer_size_returned = 0;
            return buffer_size_returned;
        } else if (retval == 0) {
            //the client just disconnected
            if (*buffer)
                free(*buffer);
            buffer_size_returned = -1;
            return buffer_size_returned;
        }
        if(retval > 0){
        	snprintf(from,16,"%s",get_in_addr_char(&their_addr));
        	printdebug("Get datas from %s\n",from);
        }
    }
    buffer_size_returned = buffer_size;
    return buffer_size_returned;
}
Beispiel #10
0
void bootmain(void)
{






/*进入30os的部分*/
struct boot_info *bootp=(struct boot_info *)ADDR_BOOT;
init_screen((struct boot_info * )bootp);
init_palette();  //color table from 0 to 15
//clear_screen(8);   	//red
//draw_window();
int mx,my;//mouse position
//display mouse logo
char mousepic[16*16];     //mouse logo buffer

//display_mouse(bootp->vram,bootp->xsize,16,16,mx,my,mousepic,16);
cli();

//set gdt idt
init_gdtidt();
//remap irq 0-15
//函数中: irq 1(keyboard)对应设置中断号int0x21,    irq 12(mouse)对应的中断号是int0x2c 要写中断服务程序了。
init_pic();

//设置完了gdt,idt后再enable cpu interrupt才是安全的

unsigned char s[40];		    //sprintf buffer
unsigned char keybuf[32];	    //keyfifo
unsigned char mousebuf[128];	//mousefifo
unsigned char data;		        //temp variable to get fifo data
int count=0;
fifo8_init(&keyfifo ,32,keybuf);//keyfifo是一个global data defined in int.c
fifo8_init(&mousefifo,128,mousebuf);

//enable timer ,keyboard and mouse   //1111 1000 后面的三个0代表 accept interrupt request, irq0=timer interrupt
outb(PIC0_IMR, 0xf8);//1111 1000  irq 1 2打开 因为keyboard是irq 1,irq2 enable 8259B 芯片发生的中断请求                                 // enable pic slave and keyboard interrupt
//enable mouse interrupt 1110 1111  irq 12 打开 mouse是irq 12  所以要把pic 1 pic 2的芯片中断响应位打开。
outb(PIC1_IMR, 0xef);
//初始化 鼠标按键控制电路
init_keyboard();

//enable cpu interrupt




unsigned int memtotal;
//get the total memory
memtotal=memtest(0x400000,0xffffffff);
//mem=mem>>20; //convert to MBytes
//sprintf(s,"memory:%dMbytes",mem);
//puts8((char *)bootp->vram ,bootp->xsize,0,100,0,s);
Memman * memman=(Memman *)0x3c0000;
memman_init(memman);
//memman_free(memman,0x1000,0x9e000);
memman_free(memman,0x400000,memtotal-0x400000);
//memman_free(memman,0x600000,0x400000);
//memman_free(memman,0xb00000,0x400000);
char *desktop=(unsigned char*)memman_alloc(memman,320*200);
printdebug(desktop,0);
//while(1);
char *win_buf=(unsigned char*)memman_alloc_4K(memman,160*65);
TIMERCTL *timerctl=(TIMERCTL *)memman_alloc_4K(memman,sizeof(TIMERCTL));
gtimerctl=timerctl;
init_pit(timerctl);//init timerctl


draw_win_buf(desktop);
make_window8(win_buf,160,68,"timer");
init_mouse(mousepic,99);	//99 means background color


sprintf(s,"memory:%dMB,free:%dMB,%d",memtotal>>20
,memman_avail(memman)>>20,memman->cellnum);
puts8(desktop ,bootp->xsize,0,150,0,s);

SHTCTL *shtctl;
shtctl=shtctl_init(memman,bootp->vram,bootp->xsize,bootp->ysize);

SHEET *sht_back,*sht_mouse,*sht_win;
//allocate a sheet space from shtctl
sht_back=sheet_alloc(shtctl);
sht_mouse=sheet_alloc(shtctl);
sht_win=sheet_alloc(shtctl);

//write something inside the window
//puts8(win_buf ,160,24,28,0,"hello ,easy os");
//puts8(win_buf ,160,24,44,0,"second line");//y=28+16=44

//hoop the buffer with sheet
sheet_setbuf(sht_back,desktop,320,200,-1);
sheet_setbuf(sht_mouse,mousepic,16,16,99);
sheet_setbuf(sht_win,win_buf,160,65,-1);

mx=0;my=0;//set mouse initial position
sheet_move(sht_back,0,0);
sheet_move(sht_mouse,mx,my);
sheet_move(sht_win,80,72);

//set sht_back to layer0 ;set sht_mouse to layer1
sheet_updown(sht_back,0);
sheet_updown(sht_win,1);
sheet_updown(sht_mouse,2);
//refresh a specific rectangle
sheet_refresh(sht_back,0,0,bootp->xsize,bootp->ysize);

struct FIFO8 timerfifo,timerfifo2,timerfifo3;
char timerbuf[8],timerbuf2[8],timerbuf3[8];
TIMER *timer,*timer2,*timer3;

fifo8_init(&timerfifo,8,timerbuf);
fifo8_init(&timerfifo2,8,timerbuf2);
fifo8_init(&timerfifo3,8,timerbuf3);

timer=timer_alloc(timerctl,0);
timer2=timer_alloc(timerctl,1);
timer3=timer_alloc(timerctl,2);

timer_init(timer,&timerfifo,1);
timer_init(timer2,&timerfifo2,1);
timer_init(timer3,&timerfifo3,1);
//while(1);
timer_settime(timer,1000,timerctl);
timer_settime(timer2,100,timerctl);
timer_settime(timer3,30,timerctl);
sti();
struct MOUSE_DEC mdec;
enable_mouse(&mdec);   //这里会产生一个mouse interrupt
while(1)
 {


    sprintf(s,"%d",timerctl->count);
    boxfill8(win_buf,160,8,20,44,140,60);
    puts8(win_buf ,160,20,44,0,s);//y=28+16=44
    sheet_refresh(sht_win,20,28,140,60);
    sti();
   if(fifo8_status(&keyfifo) +
   fifo8_status(&mousefifo)  +
   fifo8_status(&timerfifo)  +
   fifo8_status(&timerfifo2) +
   fifo8_status(&timerfifo3)
    == 0)//no data in keyfifo and mousefifo
    {
    //sti();
    //hlt();//wait for interrupt
   }
   else
   {
      if(fifo8_status(&keyfifo) != 0)
      {
        data=fifo8_read(&keyfifo);
        sti();
      }//end of keyboard decoder
      else if(fifo8_status(&mousefifo) != 0)//we have mouse interrupt data to process
      {
        data=fifo8_read(&mousefifo);
        sti();
        if(mouse_decode(&mdec,data))
        {
              //3个字节都得到了
              switch (mdec.button)
              {
                case 1:s[1]='L';break;
                case 2:s[3]='R';break;
                case 4:s[2]='M';break;
              }
              sprintf(s,"[lmr:%d %d]",mdec.x,mdec.y);
              boxfill8(desktop,320,0,32,16,32+15*8-1,33);//一个黑色的小box
              puts8(desktop,bootp->xsize,32,16,7,s);     //display e0
              sheet_refresh(sht_back,32,16,32+20*8-1,31);
        #define white 7
               //because we use sheet layer ,so we do not need this any more
              //boxfill8(p,320,white,mx,my,mx+15,my+15);//用背景色把鼠标原来的color填充,这样不会看到鼠标移动的path
              mx +=mdec.x;//mx=mx+dx
              my +=mdec.y;//my=my+dy
              if(mx<0)
              {
                mx=0;
              }
              if(my<0)
              {
                my=0;
              }


              if(mx>bootp->xsize-1)
              {
                mx=bootp->xsize-1;
              }

              if(my>bootp->ysize-1)
              {
                my=bootp->ysize-1;
              }
              sprintf(s,"(%d, %d)",mx,my);
              boxfill8(desktop,320,0,0,0,79,15);//坐标的背景色
              puts8(desktop ,bootp->xsize,0,0,7,s);//显示坐标
              sheet_refresh(sht_back,0,0,bootp->xsize,15);
              sheet_move(sht_mouse,mx,my);
        }
      }//end of mouse decoder
      else if(fifo8_status(&timerfifo)!=0)
      {
        data=fifo8_read(&timerfifo);
        sti();
        puts8(desktop ,bootp->xsize,0,64,0,"10[sec]");//显示坐标
        sheet_refresh(sht_back,0,64,bootp->xsize,80);
        //printdebug(99,80);
      }//end of timer
      else if(fifo8_status(&timerfifo2)!=0)
      {
        data=fifo8_read(&timerfifo2);
        sti();
        puts8(desktop ,bootp->xsize,0,80,0,"3[sec]");//显示坐标
        sheet_refresh(sht_back,0,80,bootp->xsize,96);
       // printdebug(16,150);
     // while(1);
      }//end of timer2
      else if(fifo8_status(&timerfifo3)!=0)//cursor blink
      {
        data=fifo8_read(&timerfifo3);
        sti();
        //static unsigned a=0;a++;//因为你没有把里面的数据读走,所以一直会进来
        //printdebug(a,0);
            if(data!=0)
            {
                timer_init(timer3,&timerfifo3,0);
                boxfill8(desktop,bootp->xsize,7,8,96,15,111);

            }
            else
            {
                timer_init(timer3,&timerfifo3,1);
                boxfill8(desktop,bootp->xsize,0,8,96,15,111);

            }
            timer_settime(timer3,50,timerctl);
            sheet_refresh(sht_back,8,96,15,111);
            sheet_refresh(sht_back,250,100,320,108);
      }//end of timer3

   }

 }
}