Exemple #1
0
/**
 * Add an event source for a GIOChannel.
 *
 * @param channel The GIOChannel.
 * @param events Events to poll on.
 * @param timeout Max time to wait before the callback is called, ignored if 0.
 * @param cb Callback function to add. Must not be NULL.
 * @param cb_data Data for the callback function. Can be NULL.
 *
 * @return SR_OK upon success, SR_ERR_ARG upon invalid arguments, or
 *         SR_ERR_MALLOC upon memory allocation errors.
 */
SR_API int sr_session_source_add_channel(GIOChannel *channel, int events,
		int timeout, sr_receive_data_callback_t cb, void *cb_data)
{
	GPollFD p;

#ifdef _WIN32
	g_io_channel_win32_make_pollfd(channel, events, &p);
#else
	p.fd = g_io_channel_unix_get_fd(channel);
	p.events = events;
#endif

	return _sr_session_source_add(&p, timeout, cb, cb_data, (gintptr)channel);
}
Exemple #2
0
/**
 * Add an event source for a GIOChannel.
 *
 * @param session The session to use. Must not be NULL.
 * @param channel The GIOChannel.
 * @param events Events to poll on.
 * @param timeout Max time in ms to wait before the callback is called,
 *                or -1 to wait indefinitely.
 * @param cb Callback function to add. Must not be NULL.
 * @param cb_data Data for the callback function. Can be NULL.
 *
 * @retval SR_OK Success.
 * @retval SR_ERR_ARG Invalid argument.
 *
 * @since 0.3.0
 * @private
 */
SR_PRIV int sr_session_source_add_channel(struct sr_session *session,
		GIOChannel *channel, int events, int timeout,
		sr_receive_data_callback cb, void *cb_data)
{
	GPollFD pollfd;

	if (!channel) {
		sr_err("%s: channel was NULL", __func__);
		return SR_ERR_ARG;
	}
	/* We should be using g_io_create_watch(), but can't without
	 * changing the driver API, as the callback signature is different.
	 */
#ifdef G_OS_WIN32
	g_io_channel_win32_make_pollfd(channel, events, &pollfd);
#else
	pollfd.fd = g_io_channel_unix_get_fd(channel);
	pollfd.events = events;
#endif
	return sr_session_fd_source_add(session, channel, pollfd.fd,
			pollfd.events, timeout, cb, cb_data);
}
Exemple #3
0
/* Select on the list of fds.  Returns: -1 = error, 0 = timeout or
   nothing to select, > 0 = number of signaled fds.  */
int
_gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock)
{
  int npollfds;
  GPollFD *pollfds;
  int *pollfds_map; 
  int i;
  int j;
  int any;
  int n;
  int count;
  /* Use a 1s timeout.  */
  int timeout = 1000;
  void *dbg_help = NULL;
  TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_select", fds,
	      "nfds=%u, nonblock=%u", nfds, nonblock);

  if (nonblock)
    timeout = 0;

  pollfds = calloc (nfds, sizeof *pollfds);
  if (!pollfds)
    return -1;
  pollfds_map = calloc (nfds, sizeof *pollfds_map);
  if (!pollfds_map)
    {
      free (pollfds);
      return -1;
    }
  npollfds = 0;

  TRACE_SEQ (dbg_help, "select on [ ");
  any = 0;
  for (i = 0; i < nfds; i++)
    {
      GIOChannel *chan = NULL;

      if (fds[i].fd == -1) 
	continue;

      if ((fds[i].for_read || fds[i].for_write)
          && !(chan = find_channel (fds[i].fd)))
        {
          TRACE_ADD1 (dbg_help, "[BAD0x%x ", fds[i].fd);
          TRACE_END (dbg_help, "]"); 
          assert (!"see log file");
        }
      else if (fds[i].for_read )
	{
          assert(chan);
          g_io_channel_win32_make_pollfd (chan, G_IO_IN, pollfds + npollfds);
          pollfds_map[npollfds] = i;
	  TRACE_ADD2 (dbg_help, "r0x%x<%d> ", fds[i].fd, pollfds[npollfds].fd);
          npollfds++;
	  any = 1;
        }
      else if (fds[i].for_write)
	{
          assert(chan);
          g_io_channel_win32_make_pollfd (chan, G_IO_OUT, pollfds + npollfds);
          pollfds_map[npollfds] = i;
	  TRACE_ADD2 (dbg_help, "w0x%x<%d> ", fds[i].fd, pollfds[npollfds].fd);
          npollfds++;
	  any = 1;
        }
      fds[i].signaled = 0;
    }
  TRACE_END (dbg_help, "]"); 
  if (!any)
    {
      count = 0;
      goto leave;
    }


  count = g_io_channel_win32_poll (pollfds, npollfds, timeout);
  if (count < 0)
    {
      int saved_errno = errno;
      errno = saved_errno;
      goto leave;
    }

  TRACE_SEQ (dbg_help, "select OK [ ");
  if (TRACE_ENABLED (dbg_help))
    {
      for (i = 0; i < npollfds; i++)
	{
	  if ((pollfds[i].revents & G_IO_IN))
	    TRACE_ADD1 (dbg_help, "r0x%x ", fds[pollfds_map[i]].fd);
          if ((pollfds[i].revents & G_IO_OUT))
            TRACE_ADD1 (dbg_help, "w0x%x ", fds[pollfds_map[i]].fd);
        }
      TRACE_END (dbg_help, "]");
    }
    
  /* COUNT is used to stop the lop as soon as possible.  */
  for (n = count, i = 0; i < npollfds && n; i++)
    {
      j = pollfds_map[i];
      assert (j >= 0 && j < nfds);
      if (fds[j].fd == -1)
	;
      else if (fds[j].for_read)
	{
	  if ((pollfds[i].revents & G_IO_IN))
	    {
	      fds[j].signaled = 1;
	      n--;
            }
        }
      else if (fds[j].for_write)
	{
	  if ((pollfds[i].revents & G_IO_OUT))
	    {
	      fds[j].signaled = 1;
	      n--;
            }
        }
    }

leave:
  free (pollfds);
  free (pollfds_map);
  return TRACE_SYSRES (count);
}
Exemple #4
0
int
main (int    argc,
      char **argv)
{
  if (argc < 3)
    {
      /* Parent */
      
      GIOChannel *my_read_channel;
      gchar *cmdline;
      guint *id;
      int i;
#ifdef G_OS_WIN32
      GTimeVal start, end;
      GPollFD pollfd;
      int pollresult;
      ATOM klass;
      static WNDCLASS wcl;
      HWND hwnd;
      GIOChannel *windows_messages_channel;
#endif

      nkiddies = (argc == 1 ? 1 : atoi(argv[1]));
      seqtab = g_malloc (nkiddies * 2 * sizeof (int));

#ifdef G_OS_WIN32
      wcl.style = 0;
      wcl.lpfnWndProc = window_procedure;
      wcl.cbClsExtra = 0;
      wcl.cbWndExtra = 0;
      wcl.hInstance = GetModuleHandle (NULL);
      wcl.hIcon = NULL;
      wcl.hCursor = NULL;
      wcl.hbrBackground = NULL;
      wcl.lpszMenuName = NULL;
      wcl.lpszClassName = "gio-test";

      klass = RegisterClass (&wcl);

      if (!klass)
	{
	  g_print ("gio-test: RegisterClass failed\n");
	  exit (1);
	}

      hwnd = CreateWindow (MAKEINTATOM(klass), "gio-test", 0, 0, 0, 10, 10,
			   NULL, NULL, wcl.hInstance, NULL);
      if (!hwnd)
	{
	  g_print ("gio-test: CreateWindow failed\n");
	  exit (1);
	}

      windows_messages_channel = g_io_channel_win32_new_messages ((guint)hwnd);
      g_io_add_watch (windows_messages_channel, G_IO_IN, recv_windows_message, 0);
#endif

      for (i = 0; i < nkiddies; i++)
	{
	  int pipe_to_sub[2], pipe_from_sub[2];
	  
	  if (pipe (pipe_to_sub) == -1 ||
	      pipe (pipe_from_sub) == -1)
	    perror ("pipe"), exit (1);
	  
	  seqtab[i].fd = pipe_from_sub[0];
	  seqtab[i].seq = 0;

	  my_read_channel = g_io_channel_unix_new (pipe_from_sub[0]);
	  
	  id = g_new (guint, 1);
	  *id =
	    g_io_add_watch (my_read_channel,
			    G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP,
			    recv_message,
			    id);
	  
	  nrunning++;
	  
#ifdef G_OS_WIN32
	  cmdline = g_strdup_printf ("%d:%d:%d",
				     pipe_to_sub[0],
				     pipe_from_sub[1],
				     hwnd);
	  _spawnl (_P_NOWAIT, argv[0], argv[0], "--child", cmdline, NULL);
#else
	  cmdline = g_strdup_printf ("%s --child %d:%d &", argv[0],
				     pipe_to_sub[0], pipe_from_sub[1]);
	  
	  system (cmdline);
#endif
	  close (pipe_to_sub[0]);
	  close (pipe_from_sub [1]);

#ifdef G_OS_WIN32
	  g_get_current_time (&start);
	  g_io_channel_win32_make_pollfd (my_read_channel, G_IO_IN, &pollfd);
	  pollresult = g_io_channel_win32_poll (&pollfd, 1, 100);
	  g_get_current_time (&end);
	  if (end.tv_usec < start.tv_usec)
	    end.tv_sec--, end.tv_usec += 1000000;
	  g_print ("gio-test: had to wait %ld.%03ld s, result:%d\n",
		   end.tv_sec - start.tv_sec,
		   (end.tv_usec - start.tv_usec) / 1000,
		   pollresult);
#endif
	}
      
      main_loop = g_main_loop_new (NULL, FALSE);
      
      g_main_loop_run (main_loop);
    }
  else if (argc == 3)
    {
      /* Child */
      
      int readfd, writefd;
#ifdef G_OS_WIN32
      HWND hwnd;
#endif
      int i, j;
      char buf[BUFSIZE];
      int buflen;
      GTimeVal tv;
      int n;
  
      g_get_current_time (&tv);
      
      sscanf (argv[2], "%d:%d%n", &readfd, &writefd, &n);

#ifdef G_OS_WIN32
      sscanf (argv[2] + n, ":%d", &hwnd);
#endif
      
      srand (tv.tv_sec ^ (tv.tv_usec / 1000) ^ readfd ^ (writefd << 4));
  
      for (i = 0; i < 20 + rand() % 20; i++)
	{
	  g_usleep (100 + (rand() % 10) * 5000);
	  buflen = rand() % BUFSIZE;
	  for (j = 0; j < buflen; j++)
	    buf[j] = ' ' + ((buflen + j) % 95);
#ifdef VERBOSE
	  g_print ("gio-test: child writing %d+%d bytes to %d\n",
		   (int)(sizeof(i) + sizeof(buflen)), buflen, writefd);
#endif
	  write (writefd, &i, sizeof (i));
	  write (writefd, &buflen, sizeof (buflen));
	  write (writefd, buf, buflen);

#ifdef G_OS_WIN32
	  if (rand() % 100 < 5)
	    {
	      int msg = WM_USER + (rand() % 100);
	      WPARAM wparam = rand ();
	      LPARAM lparam = rand ();
	      g_print ("gio-test: child posting message %d,%d,%d to %#x\n",
		       msg, wparam, lparam, hwnd);
	      PostMessage (hwnd, msg, wparam, lparam);
	    }
#endif
	}
#ifdef VERBOSE
      g_print ("gio-test: child exiting, closing %d\n", writefd);
#endif
      close (writefd);
    }
  else
    g_print ("Huh?\n");
  
  return 0;
}