Skip to content
Snippets Groups Projects
Select Git revision
  • 4170bb3215e838d9e9e8d36b439ab3223cd5fba9
  • master default
  • wip-add-ed25519
  • disable-sha1
  • lsh-2.0.4
  • experimental-20050201
  • lsh-1.4.2
  • lsh-1.2
  • lsh_2.1_release_20130626
  • converted-master-branch-to-git
  • nettle_2.4_release_20110903
  • nettle_2.3_release_20110902
  • nettle_2.2_release_20110711
  • nettle_2.1_release_20100725
  • camellia_32bit_20100720
  • nettle_2.0_release_20090608
  • converted-lsh-2.0.4-branch-to-git
  • lsh_2.0.4_release_20070905
  • lsh_2.9_exp_release_20070404
  • nettle_1.15_release_20061128
  • after_experimental_merge_20060516
  • branch_before_experimental_merge_20060516
  • converted-experimental-branch-to-git
  • head_before_experimental_merge_20060516
  • lsh_2.0.3_release_20060509
  • lsh_2.0.2_release_20060127
  • nettle_1.14_release_20051205
  • nettle_1.13_release_20051006
28 results

write_buffer.h

Blame
  • backend.c 5.52 KiB
    /*\
    ||| This file a part of Pike, and is copyright by Fredrik Hubinette
    ||| Pike is distributed as GPL (General Public License)
    ||| See the files COPYING and DISCLAIMER for more information.
    \*/
    #include "global.h"
    RCSID("$Id: backend.c,v 1.8 1997/01/26 22:47:03 per Exp $");
    #include "backend.h"
    #include <errno.h>
    #ifdef HAVE_SYS_TYPES_H
    #include <sys/types.h>
    #endif
    #include <sys/param.h>
    #include <string.h>
    #include "interpret.h"
    #include "object.h"
    #include "types.h"
    #include "error.h"
    #include "fd_control.h"
    #include "main.h"
    #include "callback.h"
    #include "threads.h"
    
    #ifdef HAVE_SYS_SELECT_H
    #include <sys/select.h>
    #endif
    
    #define SELECT_READ 1
    #define SELECT_WRITE 2
    
    struct selectors
    {
      fd_set read;
      fd_set write;
    };
    
    static struct selectors selectors;
    
    file_callback read_callback[MAX_OPEN_FILEDESCRIPTORS];
    void *read_callback_data[MAX_OPEN_FILEDESCRIPTORS];
    file_callback write_callback[MAX_OPEN_FILEDESCRIPTORS];
    void *write_callback_data[MAX_OPEN_FILEDESCRIPTORS];
    
    static int max_fd;
    struct timeval current_time;
    struct timeval next_timeout;
    
    static struct callback_list backend_callbacks;
    
    struct callback *add_backend_callback(callback_func call,
    				      void *arg,
    				      callback_func free_func)
    {
      return add_to_callback(&backend_callbacks, call, arg, free_func);
    }
    
    void init_backend()
    {
      FD_ZERO(&selectors.read);
      FD_ZERO(&selectors.write);
    }
    
    void set_read_callback(int fd,file_callback cb,void *data)
    {
    #ifdef DEBUG
      if(fd<0 || fd>=MAX_OPEN_FILEDESCRIPTORS)
        fatal("File descriptor out of range.\n %d",fd);
    #endif
    
      read_callback[fd]=cb;
      read_callback_data[fd]=data;
    
      if(cb)
      {
        FD_SET(fd, &selectors.read);
        if(max_fd < fd) max_fd = fd;
      }else{
        if(fd <= max_fd)
        {
          FD_CLR(fd, &selectors.read);
          if(fd == max_fd)
          {
    	while(max_fd >=0 &&
    	      !FD_ISSET(max_fd, &selectors.read) &&
    	      !FD_ISSET(max_fd, &selectors.write))
    	  max_fd--;
          }
        }
      }
    }
    
    void set_write_callback(int fd,file_callback cb,void *data)
    {
    #ifdef DEBUG
      if(fd<0 || fd>=MAX_OPEN_FILEDESCRIPTORS)
        fatal("File descriptor out of range.\n %d",fd);
    #endif
    
      write_callback[fd]=cb;
      write_callback_data[fd]=data;
    
      if(cb)
      {
        FD_SET(fd, &selectors.write);
        if(max_fd < fd) max_fd = fd;
      }else{
        if(fd <= max_fd)
        {
          FD_CLR(fd, &selectors.write);
          if(fd == max_fd)
          {
    	while(max_fd >=0 &&
    	      !FD_ISSET(max_fd, &selectors.read) &&
    	      !FD_ISSET(max_fd, &selectors.write))
    	  max_fd--;
          }
        }
      }
    }
    
    file_callback query_read_callback(int fd)
    {
    #ifdef DEBUG
      if(fd<0 || fd>=MAX_OPEN_FILEDESCRIPTORS)
        fatal("File descriptor out of range.\n %d",fd);
    #endif
    
      return read_callback[fd];
    }
    
    file_callback query_write_callback(int fd)
    {
    #ifdef DEBUG
      if(fd<0 || fd>=MAX_OPEN_FILEDESCRIPTORS)
        fatal("File descriptor out of range.\n %d",fd);
    #endif
    
      return write_callback[fd];
    }
    
    void *query_read_callback_data(int fd)
    {
    #ifdef DEBUG
      if(fd<0 || fd>=MAX_OPEN_FILEDESCRIPTORS)
        fatal("File descriptor out of range.\n %d",fd);
    #endif
    
      return read_callback_data[fd];
    }
    
    void *query_write_callback_data(int fd)
    {
    #ifdef DEBUG
      if(fd<0 || fd>=MAX_OPEN_FILEDESCRIPTORS)
        fatal("File descriptor out of range.\n %d",fd);
    #endif
    
      return write_callback_data[fd];
    }
    
    #ifdef DEBUG
    void do_debug()
    {
      extern void check_all_arrays();
      extern void check_all_mappings();
      extern void check_all_programs();
      extern void check_all_objects();
      extern void verify_shared_strings_tables();
      extern void slow_check_stack();
    
      slow_check_stack();
      check_all_arrays();
      check_all_mappings();
      check_all_programs();
      verify_all_objects();
      verify_shared_strings_tables();
    }
    #endif
    
    void backend()
    {
      JMP_BUF back;
      int i, delay;
      struct selectors sets;
    
      if(SETJMP(back))
      {
        ONERROR tmp;
        SET_ONERROR(tmp,exit_on_error,"Error in handle_error in master object!");
        assign_svalue_no_free(sp++, & throw_value);
        APPLY_MASTER("handle_error", 1);
        pop_stack();
        UNSET_ONERROR(tmp);
      }
    
      while(first_object)
      {
        next_timeout.tv_usec = 0;
        next_timeout.tv_sec = 7 * 24 * 60 * 60;  /* See you in a week */
        my_add_timeval(&next_timeout, &current_time);
    
        call_callback(& backend_callbacks, (void *)0);
    
        check_threads_etc();
    
        sets=selectors;
    
        alloca(0);			/* Do garbage collect */
    #ifdef DEBUG
        if(d_flag > 1) do_debug();
    #endif
    
        GETTIMEOFDAY(&current_time);
    
        if(my_timercmp(&next_timeout, > , &current_time))
        {
          my_subtract_timeval(&next_timeout, &current_time);
        }else{
          next_timeout.tv_usec = 0;
          next_timeout.tv_sec = 0;
        }
    
        THREADS_ALLOW();
        i=select(max_fd+1, &sets.read, &sets.write, 0, &next_timeout);
        GETTIMEOFDAY(&current_time);
        THREADS_DISALLOW();
    
        if(i>=0)
        {
          for(i=0; i<max_fd+1; i++)
          {
    	if(FD_ISSET(i, &sets.read) && read_callback[i])
    	  (*(read_callback[i]))(i,read_callback_data[i]);
    
    	if(FD_ISSET(i, &sets.write) && write_callback[i])
    	  (*(write_callback[i]))(i,write_callback_data[i]);
          }
        }else{
          switch(errno)
          {
          case EINVAL:
    	fatal("Invalid timeout to select().\n");
    	break;
    
          case EINTR:		/* ignore */
    	break;
    
          case EBADF:
    /*	fatal("Bad filedescriptor to select().\n");  Ignore */
    	break;
    
          }
        }
        call_callback(& backend_callbacks, (void *)1);
      }
    
      UNSETJMP(back);
    }
    
    int write_to_stderr(char *a, INT32 len)
    {
      int nonblock;
      INT32 pos, tmp;
    
      if((nonblock=query_nonblocking(2)))
        set_nonblocking(2,0);
    
      for(pos=0;pos<len;pos+=tmp)
      {
        tmp=write(2,a+pos,len-pos);
        if(tmp<0) break;
      }
      if(nonblock)
        set_nonblocking(2,1);
      return 1;
    }