Ejemplo n.º 1
0
static gboolean
inf_tcp_connection_open_real(InfTcpConnection* connection,
                             const InfIpAddress* address,
                             guint port,
                             GError** error)
{
  InfTcpConnectionPrivate* priv;

  union {
    struct sockaddr_in in;
    struct sockaddr_in6 in6;
  } native_address;

  struct sockaddr* addr;
  socklen_t addrlen;
  int result;
  int errcode;
  const InfKeepalive* keepalive;
  GError* local_error;

  priv = INF_TCP_CONNECTION_PRIVATE(connection);

  g_assert(priv->status == INF_TCP_CONNECTION_CLOSED ||
           priv->status == INF_TCP_CONNECTION_CONNECTING);

  /* Close previous socket */
  if(priv->socket != INVALID_SOCKET)
    closesocket(priv->socket);

  switch(inf_ip_address_get_family(address))
  {
  case INF_IP_ADDRESS_IPV4:
    priv->socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    addr = (struct sockaddr*)&native_address.in;
    addrlen = sizeof(struct sockaddr_in);

    memcpy(
      &native_address.in.sin_addr,
      inf_ip_address_get_raw(address),
      sizeof(struct in_addr)
    );

    native_address.in.sin_family = AF_INET;
    native_address.in.sin_port = htons(port);

    break;
  case INF_IP_ADDRESS_IPV6:
    priv->socket = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP);
    addr = (struct sockaddr*)&native_address.in6;
    addrlen = sizeof(struct sockaddr_in6);

    memcpy(
      &native_address.in6.sin6_addr,
      inf_ip_address_get_raw(address),
      sizeof(struct in6_addr)
    );

    native_address.in6.sin6_family = AF_INET6;
    native_address.in6.sin6_port = htons(port);
    native_address.in6.sin6_flowinfo = 0;
    native_address.in6.sin6_scope_id = priv->device_index;

    break;
  default:
    g_assert_not_reached();
    break;
  }

  if(priv->socket == INVALID_SOCKET)
  {
    inf_native_socket_make_error(INF_NATIVE_SOCKET_LAST_ERROR, error);
    return FALSE;
  }

  /* Set socket non-blocking and keepalive */
  keepalive = &priv->keepalive;
  if(!inf_tcp_connection_configure_socket(priv->socket, keepalive, error))
  {
    closesocket(priv->socket);
    priv->socket = INVALID_SOCKET;
    return FALSE;
  }

  /* Connect */
  do
  {
    result = connect(priv->socket, addr, addrlen);
    errcode = INF_NATIVE_SOCKET_LAST_ERROR;
    if(result == -1 &&
       errcode != INF_NATIVE_SOCKET_EINTR &&
       errcode != INF_NATIVE_SOCKET_EINPROGRESS)
    {
      local_error = NULL;
      inf_native_socket_make_error(errcode, &local_error);
      if(inf_tcp_connection_connection_error(connection, local_error) == TRUE)
      {
        /* In this case, we could recover from the error by connecting to a
         * different address. */
        g_error_free(local_error);
        return TRUE;
      }

      g_propagate_error(error, local_error);
      return FALSE;
    }
  } while(result == -1 && errcode != INF_NATIVE_SOCKET_EINPROGRESS);

  if(result == 0)
  {
    /* Connection fully established */
    inf_tcp_connection_connected(connection);
  }
  else
  {
    g_assert(priv->watch == NULL);

    /* Connection establishment in progress */
    priv->events = INF_IO_OUTGOING | INF_IO_ERROR;

    priv->watch = inf_io_add_watch(
      priv->io,
      &priv->socket,
      priv->events,
      inf_tcp_connection_io,
      connection,
      NULL
    );

    if(priv->status != INF_TCP_CONNECTION_CONNECTING)
    {
      priv->status = INF_TCP_CONNECTION_CONNECTING;
      g_object_notify(G_OBJECT(connection), "status");
    }
  }

  return TRUE;
}
Ejemplo n.º 2
0
static void
test_gles2_read_pixels (void)
{
  CoglTexture *offscreen_texture;
  CoglOffscreen *offscreen;
  CoglPipeline *pipeline;
  CoglGLES2Context *gles2_ctx;
  const CoglGLES2Vtable *gles2;
  GError *error = NULL;
  GLubyte pixel[3];
  GLuint fbo_handle;

  create_gles2_context (&offscreen_texture,
                        &offscreen,
                        &pipeline,
                        &gles2_ctx,
                        &gles2);

  cogl_framebuffer_clear4f (test_fb, COGL_BUFFER_BIT_COLOR, 1, 1, 1, 1);

  if (!cogl_push_gles2_context (test_ctx,
                                gles2_ctx,
                                COGL_FRAMEBUFFER (offscreen),
                                COGL_FRAMEBUFFER (offscreen),
                                &error))
    {
      g_error ("Failed to push gles2 context: %s\n", error->message);
    }

  gles2->glClearColor (1, 0, 0, 1);
  gles2->glClear (GL_COLOR_BUFFER_BIT);
  gles2->glReadPixels (0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixel);

  g_assert (pixel[0] == 0xff);
  g_assert (pixel[1] == 0);
  g_assert (pixel[2] == 0);

  fbo_handle = create_gles2_framebuffer (gles2, 256, 256);

  gles2->glBindFramebuffer (GL_FRAMEBUFFER, fbo_handle);

  gles2->glClearColor (0, 1, 0, 1);
  gles2->glClear (GL_COLOR_BUFFER_BIT);
  gles2->glReadPixels (0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixel);

  g_assert (pixel[0] == 0);
  g_assert (pixel[1] == 0xff);
  g_assert (pixel[2] == 0);

  gles2->glBindFramebuffer (GL_FRAMEBUFFER, 0);

  gles2->glClearColor (0, 1, 1, 1);
  gles2->glClear (GL_COLOR_BUFFER_BIT);
  gles2->glReadPixels (0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixel);

  g_assert (pixel[0] == 0);
  g_assert (pixel[1] == 0xff);
  g_assert (pixel[2] == 0xff);

  cogl_pop_gles2_context (test_ctx);

  test_utils_check_pixel (test_fb, 0, 0, 0xffffffff);

  /* Bind different read and write buffers */
  if (!cogl_push_gles2_context (test_ctx,
                                gles2_ctx,
                                COGL_FRAMEBUFFER (offscreen),
                                test_fb,
                                &error))
    {
      g_error ("Failed to push gles2 context: %s\n", error->message);
    }

  gles2->glReadPixels (0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixel);

  g_assert (pixel[0] == 0);
  g_assert (pixel[1] == 0xff);
  g_assert (pixel[2] == 0xff);

  cogl_pop_gles2_context (test_ctx);

  test_utils_check_pixel (test_fb, 0, 0, 0xffffffff);

  /* Bind different read and write buffers (the other way around from
   * before so when we test with COGL_TEST_ONSCREEN=1 we will read
   * from an onscreen framebuffer) */
  if (!cogl_push_gles2_context (test_ctx,
                                gles2_ctx,
                                test_fb,
                                COGL_FRAMEBUFFER (offscreen),
                                &error))
    {
      g_error ("Failed to push gles2 context: %s\n", error->message);
    }

  gles2->glReadPixels (0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixel);

  g_assert (pixel[0] == 0xff);
  g_assert (pixel[1] == 0xff);
  g_assert (pixel[2] == 0xff);

  cogl_pop_gles2_context (test_ctx);
}
Ejemplo n.º 3
0
static GdkVisual*
gdk_gix_screen_visual_get_best (GdkScreen *screen)
{
  g_assert(system_visual != NULL);
  return system_visual;
}
Ejemplo n.º 4
0
static void set_persistent_state_defaults(GAPersistentState *pstate)
{
    g_assert(pstate);
    pstate->fd_counter = QGA_PSTATE_DEFAULT_FD_COUNTER;
}
Ejemplo n.º 5
0
void
sgen_workers_wake_up_all (void)
{
    g_assert (workers_state.data.gc_in_progress);
    workers_wake_up_all ();
}
Ejemplo n.º 6
0
int
main (int argc, char *argv[])
{
  GstElement *bin, *videotestsrc, *appsink;
  GstFormat format;
  gint64 pos;

  gst_init (&argc, &argv);

  /* create a new bin to hold the elements */
  bin = gst_pipeline_new ("pipeline");
  g_assert (bin);

  /* create a fake source */
  videotestsrc = gst_element_factory_make ("videotestsrc", "videotestsrc");
  g_assert (videotestsrc);
  g_object_set (videotestsrc, "num-buffers", 10, NULL);

  /* and a fake sink */
  appsink = gst_element_factory_make ("appsink", "appsink");
  g_assert (appsink);
  g_object_set (appsink, "emit-signals", TRUE, NULL);
  g_object_set (appsink, "sync", TRUE, NULL);
  g_signal_connect (appsink, "new-preroll", (GCallback) new_preroll, NULL);

  /* add objects to the main pipeline */
  gst_bin_add (GST_BIN (bin), videotestsrc);
  gst_bin_add (GST_BIN (bin), appsink);

  /* link the elements */
  gst_element_link_many (videotestsrc, appsink, NULL);

  /* go to the PAUSED state and wait for preroll */
  g_message ("prerolling first frame");
  gst_element_set_state (bin, GST_STATE_PAUSED);
  gst_element_get_state (bin, NULL, NULL, -1);

  /* step two frames, flush so that new preroll is queued */
  g_message ("stepping three frames");
  g_assert (gst_element_send_event (bin,
          gst_event_new_step (GST_FORMAT_BUFFERS, 2, 1.0, TRUE, FALSE)));

  /* blocks and returns when we received the step done message */
  event_loop (bin);

  /* wait for step to really complete */
  gst_element_get_state (bin, NULL, NULL, -1);

  format = GST_FORMAT_TIME;
  gst_element_query_position (bin, &format, &pos);
  g_message ("stepped two frames, now at %" GST_TIME_FORMAT,
      GST_TIME_ARGS (pos));

  /* step 3 frames, flush so that new preroll is queued */
  g_message ("stepping 120 milliseconds ");
  g_assert (gst_element_send_event (bin,
          gst_event_new_step (GST_FORMAT_TIME, 120 * GST_MSECOND, 1.0, TRUE,
              FALSE)));

  /* blocks and returns when we received the step done message */
  event_loop (bin);

  /* wait for step to really complete */
  gst_element_get_state (bin, NULL, NULL, -1);

  format = GST_FORMAT_TIME;
  gst_element_query_position (bin, &format, &pos);
  g_message ("stepped 120ms frames, now at %" GST_TIME_FORMAT,
      GST_TIME_ARGS (pos));

  g_message ("playing until EOS");
  gst_element_set_state (bin, GST_STATE_PLAYING);
  /* Run event loop listening for bus messages until EOS or ERROR */
  event_loop (bin);
  g_message ("finished");

  /* stop the bin */
  gst_element_set_state (bin, GST_STATE_NULL);

  exit (0);
}
static void
test_taglib_apev2mux_with_tags (GstTagList * tags, guint32 mask)
{
  GstMessage *msg;
  GstTagList *tags_read = NULL;
  GstElement *pipeline, *apev2mux, *apedemux, *fakesrc, *fakesink;
  GstBus *bus;
  guint64 offset;
  GstBuffer *outbuf = NULL;

  pipeline = gst_pipeline_new ("pipeline");
  g_assert (pipeline != NULL);

  fakesrc = gst_element_factory_make ("fakesrc", "fakesrc");
  g_assert (fakesrc != NULL);

  apev2mux = gst_element_factory_make ("apev2mux", "apev2mux");
  g_assert (apev2mux != NULL);

  apedemux = gst_element_factory_make ("apedemux", "apedemux");
  g_assert (apedemux != NULL);

  fakesink = gst_element_factory_make ("fakesink", "fakesink");
  g_assert (fakesink != NULL);

  /* set up sink */
  outbuf = NULL;
  g_object_set (fakesink, "signal-handoffs", TRUE, NULL);
  g_signal_connect (fakesink, "handoff", G_CALLBACK (got_buffer), &outbuf);

  gst_bin_add (GST_BIN (pipeline), fakesrc);
  gst_bin_add (GST_BIN (pipeline), apev2mux);
  gst_bin_add (GST_BIN (pipeline), apedemux);
  gst_bin_add (GST_BIN (pipeline), fakesink);

  gst_tag_setter_merge_tags (GST_TAG_SETTER (apev2mux), tags,
      GST_TAG_MERGE_APPEND);

  gst_element_link_many (fakesrc, apev2mux, apedemux, fakesink, NULL);

  /* set up source */
  g_object_set (fakesrc, "signal-handoffs", TRUE, "can-activate-pull", FALSE,
      "filltype", 2, "sizetype", 2, "sizemax", MP3_FRAME_SIZE,
      "num-buffers", 16, NULL);

  offset = 0;
  g_signal_connect (fakesrc, "handoff", G_CALLBACK (fill_mp3_buffer), &offset);

  gst_element_set_state (pipeline, GST_STATE_PLAYING);
  fail_unless (gst_element_get_state (pipeline, NULL, NULL,
          -1) == GST_STATE_CHANGE_SUCCESS);

  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));

  GST_LOG ("Waiting for tag ...");
  msg =
      gst_bus_poll (bus, GST_MESSAGE_TAG | GST_MESSAGE_EOS | GST_MESSAGE_ERROR,
      -1);
  if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) {
    GError *err;
    gchar *dbg;

    gst_message_parse_error (msg, &err, &dbg);
    g_printerr ("ERROR from element %s: %s\n%s\n",
        GST_OBJECT_NAME (msg->src), err->message, GST_STR_NULL (dbg));
    g_error_free (err);
    g_free (dbg);
  } else if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_EOS) {
    g_printerr ("EOS message, but were waiting for TAGS!\n");
  }
  fail_unless (msg->type == GST_MESSAGE_TAG);

  gst_message_parse_tag (msg, &tags_read);
  gst_message_unref (msg);

  GST_LOG ("Got tags: %" GST_PTR_FORMAT, tags_read);
  test_taglib_apev2mux_check_tags (tags_read, mask);
  gst_tag_list_unref (tags_read);

  GST_LOG ("Waiting for EOS ...");
  msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1);
  if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) {
    GError *err;
    gchar *dbg;

    gst_message_parse_error (msg, &err, &dbg);
    g_printerr ("ERROR from element %s: %s\n%s\n",
        GST_OBJECT_NAME (msg->src), err->message, GST_STR_NULL (dbg));
    g_error_free (err);
    g_free (dbg);
  }
  fail_unless (msg->type == GST_MESSAGE_EOS);
  gst_message_unref (msg);

  gst_object_unref (bus);

  GST_LOG ("Got EOS, shutting down ...");
  gst_element_set_state (pipeline, GST_STATE_NULL);
  gst_object_unref (pipeline);

  test_taglib_apev2mux_check_output_buffer (outbuf);
  gst_buffer_unref (outbuf);

  GST_LOG ("Done");
}
Ejemplo n.º 8
0
static void
wait_callback (gint fd, gint events, gpointer user_data)
{
	MonoError error;

	if (mono_runtime_is_shutting_down ())
		return;

	if (fd == threadpool_io->wakeup_pipes [0]) {
		mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_THREADPOOL, "io threadpool: wke");
		selector_thread_wakeup_drain_pipes ();
	} else {
		MonoGHashTable *states;
		MonoMList *list = NULL;
		gpointer k;
		gboolean remove_fd = FALSE;
		gint operations;

		g_assert (user_data);
		states = (MonoGHashTable *)user_data;

		mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_THREADPOOL, "io threadpool: cal fd %3d, events = %2s | %2s | %3s",
			fd, (events & EVENT_IN) ? "RD" : "..", (events & EVENT_OUT) ? "WR" : "..", (events & EVENT_ERR) ? "ERR" : "...");

		if (!mono_g_hash_table_lookup_extended (states, GINT_TO_POINTER (fd), &k, (gpointer*) &list))
			g_error ("wait_callback: fd %d not found in states table", fd);

		if (list && (events & EVENT_IN) != 0) {
			MonoIOSelectorJob *job = get_job_for_event (&list, EVENT_IN);
			if (job) {
				mono_threadpool_ms_enqueue_work_item (((MonoObject*) job)->vtable->domain, (MonoObject*) job, &error);
				mono_error_assert_ok (&error);
			}

		}
		if (list && (events & EVENT_OUT) != 0) {
			MonoIOSelectorJob *job = get_job_for_event (&list, EVENT_OUT);
			if (job) {
				mono_threadpool_ms_enqueue_work_item (((MonoObject*) job)->vtable->domain, (MonoObject*) job, &error);
				mono_error_assert_ok (&error);
			}
		}

		remove_fd = (events & EVENT_ERR) == EVENT_ERR;
		if (!remove_fd) {
			mono_g_hash_table_replace (states, GINT_TO_POINTER (fd), list);

			operations = get_operations_for_jobs (list);

			mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_THREADPOOL, "io threadpool: res fd %3d, events = %2s | %2s | %3s",
				fd, (operations & EVENT_IN) ? "RD" : "..", (operations & EVENT_OUT) ? "WR" : "..", (operations & EVENT_ERR) ? "ERR" : "...");

			threadpool_io->backend.register_fd (fd, operations, FALSE);
		} else {
			mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_THREADPOOL, "io threadpool: err fd %d", fd);

			mono_g_hash_table_remove (states, GINT_TO_POINTER (fd));

			threadpool_io->backend.remove_fd (fd);
		}
	}
}
Ejemplo n.º 9
0
static void
selector_thread (gpointer data)
{
	MonoError error;
	MonoGHashTable *states;

	io_selector_running = TRUE;

	if (mono_runtime_is_shutting_down ()) {
		io_selector_running = FALSE;
		return;
	}

	states = mono_g_hash_table_new_type (g_direct_hash, g_direct_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_THREAD_POOL, "i/o thread pool states table");

	for (;;) {
		gint i, j;
		gint res;

		mono_coop_mutex_lock (&threadpool_io->updates_lock);

		for (i = 0; i < threadpool_io->updates_size; ++i) {
			ThreadPoolIOUpdate *update = &threadpool_io->updates [i];

			switch (update->type) {
			case UPDATE_EMPTY:
				break;
			case UPDATE_ADD: {
				gint fd;
				gint operations;
				gpointer k;
				gboolean exists;
				MonoMList *list = NULL;
				MonoIOSelectorJob *job;

				fd = update->data.add.fd;
				g_assert (fd >= 0);

				job = update->data.add.job;
				g_assert (job);

				exists = mono_g_hash_table_lookup_extended (states, GINT_TO_POINTER (fd), &k, (gpointer*) &list);
				list = mono_mlist_append_checked (list, (MonoObject*) job, &error);
				mono_error_assert_ok (&error);
				mono_g_hash_table_replace (states, GINT_TO_POINTER (fd), list);

				operations = get_operations_for_jobs (list);

				mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_THREADPOOL, "io threadpool: %3s fd %3d, operations = %2s | %2s | %3s",
					exists ? "mod" : "add", fd, (operations & EVENT_IN) ? "RD" : "..", (operations & EVENT_OUT) ? "WR" : "..", (operations & EVENT_ERR) ? "ERR" : "...");

				threadpool_io->backend.register_fd (fd, operations, !exists);

				break;
			}
			case UPDATE_REMOVE_SOCKET: {
				gint fd;
				gpointer k;
				MonoMList *list = NULL;

				fd = update->data.remove_socket.fd;
				g_assert (fd >= 0);

				if (mono_g_hash_table_lookup_extended (states, GINT_TO_POINTER (fd), &k, (gpointer*) &list)) {
					mono_g_hash_table_remove (states, GINT_TO_POINTER (fd));

					for (j = i + 1; j < threadpool_io->updates_size; ++j) {
						ThreadPoolIOUpdate *update = &threadpool_io->updates [j];
						if (update->type == UPDATE_ADD && update->data.add.fd == fd)
							memset (update, 0, sizeof (ThreadPoolIOUpdate));
					}

					for (; list; list = mono_mlist_remove_item (list, list)) {
						mono_threadpool_ms_enqueue_work_item (mono_object_domain (mono_mlist_get_data (list)), mono_mlist_get_data (list), &error);
						mono_error_assert_ok (&error);
					}

					mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_THREADPOOL, "io threadpool: del fd %3d", fd);
					threadpool_io->backend.remove_fd (fd);
				}

				break;
			}
			case UPDATE_REMOVE_DOMAIN: {
				MonoDomain *domain;

				domain = update->data.remove_domain.domain;
				g_assert (domain);

				FilterSockaresForDomainData user_data = { .domain = domain, .states = states };
				mono_g_hash_table_foreach (states, filter_jobs_for_domain, &user_data);

				for (j = i + 1; j < threadpool_io->updates_size; ++j) {
					ThreadPoolIOUpdate *update = &threadpool_io->updates [j];
					if (update->type == UPDATE_ADD && mono_object_domain (update->data.add.job) == domain)
						memset (update, 0, sizeof (ThreadPoolIOUpdate));
				}

				break;
			}
			default:
				g_assert_not_reached ();
			}
		}

		mono_coop_cond_broadcast (&threadpool_io->updates_cond);

		if (threadpool_io->updates_size > 0) {
			threadpool_io->updates_size = 0;
			memset (&threadpool_io->updates, 0, UPDATES_CAPACITY * sizeof (ThreadPoolIOUpdate));
		}

		mono_coop_mutex_unlock (&threadpool_io->updates_lock);

		mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_THREADPOOL, "io threadpool: wai");

		res = threadpool_io->backend.event_wait (wait_callback, states);

		if (res == -1 || mono_runtime_is_shutting_down ())
			break;
	}

	mono_g_hash_table_destroy (states);

	io_selector_running = FALSE;
}
Ejemplo n.º 10
0
/*
 * Note: This has the side effect of munlock'ing all of RAM, that's
 * normally fine since if the postcopy succeeds it gets turned back on at the
 * end.
 */
bool postcopy_ram_supported_by_host(MigrationIncomingState *mis)
{
    long pagesize = getpagesize();
    int ufd = -1;
    bool ret = false; /* Error unless we change it */
    void *testarea = NULL;
    struct uffdio_register reg_struct;
    struct uffdio_range range_struct;
    uint64_t feature_mask;
    Error *local_err = NULL;

    if (qemu_target_page_size() > pagesize) {
        error_report("Target page size bigger than host page size");
        goto out;
    }

    ufd = syscall(__NR_userfaultfd, O_CLOEXEC);
    if (ufd == -1) {
        error_report("%s: userfaultfd not available: %s", __func__,
                     strerror(errno));
        goto out;
    }

    /* Give devices a chance to object */
    if (postcopy_notify(POSTCOPY_NOTIFY_PROBE, &local_err)) {
        error_report_err(local_err);
        goto out;
    }

    /* Version and features check */
    if (!ufd_check_and_apply(ufd, mis)) {
        goto out;
    }

    /* We don't support postcopy with shared RAM yet */
    if (qemu_ram_foreach_migratable_block(test_ramblock_postcopiable, NULL)) {
        goto out;
    }

    /*
     * userfault and mlock don't go together; we'll put it back later if
     * it was enabled.
     */
    if (munlockall()) {
        error_report("%s: munlockall: %s", __func__,  strerror(errno));
        return -1;
    }

    /*
     *  We need to check that the ops we need are supported on anon memory
     *  To do that we need to register a chunk and see the flags that
     *  are returned.
     */
    testarea = mmap(NULL, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE |
                                    MAP_ANONYMOUS, -1, 0);
    if (testarea == MAP_FAILED) {
        error_report("%s: Failed to map test area: %s", __func__,
                     strerror(errno));
        goto out;
    }
    g_assert(((size_t)testarea & (pagesize-1)) == 0);

    reg_struct.range.start = (uintptr_t)testarea;
    reg_struct.range.len = pagesize;
    reg_struct.mode = UFFDIO_REGISTER_MODE_MISSING;

    if (ioctl(ufd, UFFDIO_REGISTER, &reg_struct)) {
        error_report("%s userfault register: %s", __func__, strerror(errno));
        goto out;
    }

    range_struct.start = (uintptr_t)testarea;
    range_struct.len = pagesize;
    if (ioctl(ufd, UFFDIO_UNREGISTER, &range_struct)) {
        error_report("%s userfault unregister: %s", __func__, strerror(errno));
        goto out;
    }

    feature_mask = (__u64)1 << _UFFDIO_WAKE |
                   (__u64)1 << _UFFDIO_COPY |
                   (__u64)1 << _UFFDIO_ZEROPAGE;
    if ((reg_struct.ioctls & feature_mask) != feature_mask) {
        error_report("Missing userfault map features: %" PRIx64,
                     (uint64_t)(~reg_struct.ioctls & feature_mask));
        goto out;
    }

    /* Success! */
    ret = true;
out:
    if (testarea) {
        munmap(testarea, pagesize);
    }
    if (ufd != -1) {
        close(ufd);
    }
    return ret;
}
Ejemplo n.º 11
0
static void
gnc_split_register_layout_add_cursors (SplitRegister *reg,
                                       TableLayout *layout)
{
    CellBlock *cursor;
    int num_cols;

    switch (reg->type)
    {
    case BANK_REGISTER:
    case CASH_REGISTER:
    case ASSET_REGISTER:
    case CREDIT_REGISTER:
    case LIABILITY_REGISTER:
    case INCOME_REGISTER:
    case EXPENSE_REGISTER:
    case EQUITY_REGISTER:
    case TRADING_REGISTER:
        num_cols = 9;
        break;

    case PAYABLE_REGISTER:
    case RECEIVABLE_REGISTER:
        num_cols = 9;
        break;

    case INCOME_LEDGER:
    case GENERAL_LEDGER:
    case SEARCH_LEDGER:
        if (reg->is_template)
            num_cols = 8;
        else
            num_cols = 9;
        break;

    case STOCK_REGISTER:
    case CURRENCY_REGISTER:
        num_cols = 10;
        break;

    case PORTFOLIO_LEDGER:
        num_cols = 9;
        break;

    default:
        PERR("Bad register type");
        g_assert (FALSE);
        return;
    }

    cursor = gnc_cellblock_new (1, num_cols, CURSOR_HEADER);
    gnc_table_layout_add_cursor (layout, cursor);

    /* cursors used in ledger mode */
    cursor = gnc_cellblock_new (1, num_cols, CURSOR_SINGLE_LEDGER);
    gnc_table_layout_add_cursor (layout, cursor);

    gnc_table_layout_set_primary_cursor (layout, cursor);

    cursor = gnc_cellblock_new (2, num_cols, CURSOR_DOUBLE_LEDGER);
    gnc_table_layout_add_cursor (layout, cursor);

    cursor = gnc_cellblock_new (2, num_cols, CURSOR_DOUBLE_LEDGER_NUM_ACTN);
    gnc_table_layout_add_cursor (layout, cursor);

    /* cursors used for journal mode */
    cursor = gnc_cellblock_new (1, num_cols, CURSOR_SINGLE_JOURNAL);
    gnc_table_layout_add_cursor (layout, cursor);

    cursor = gnc_cellblock_new (2, num_cols, CURSOR_DOUBLE_JOURNAL);
    gnc_table_layout_add_cursor (layout, cursor);

    cursor = gnc_cellblock_new (2, num_cols, CURSOR_DOUBLE_JOURNAL_NUM_ACTN);
    gnc_table_layout_add_cursor (layout, cursor);

    cursor = gnc_cellblock_new (1, num_cols, CURSOR_SPLIT);
    gnc_table_layout_add_cursor (layout, cursor);
}
Ejemplo n.º 12
0
static void
inf_tcp_connection_set_property(GObject* object,
                                guint prop_id,
                                const GValue* value,
                                GParamSpec* pspec)
{
  InfTcpConnection* connection;
  InfTcpConnectionPrivate* priv;
#ifndef G_OS_WIN32
  const gchar* device_string;
  unsigned int new_index;
#endif
  GError* error;

  connection = INF_TCP_CONNECTION(object);
  priv = INF_TCP_CONNECTION_PRIVATE(connection);

  switch(prop_id)
  {
  case PROP_IO:
    g_assert(priv->status == INF_TCP_CONNECTION_CLOSED);
    if(priv->io != NULL) g_object_unref(G_OBJECT(priv->io));
    priv->io = INF_IO(g_value_dup_object(value));
    break;
  case PROP_RESOLVER:
    g_assert(priv->status == INF_TCP_CONNECTION_CLOSED);

    inf_tcp_connection_set_resolver(
      connection,
      INF_NAME_RESOLVER(g_value_get_object(value))
    );

    break;
  case PROP_KEEPALIVE:
    error = NULL;

    inf_tcp_connection_set_keepalive(
      connection,
      (InfKeepalive*)g_value_get_boxed(value),
      &error
    );
    
    if(error != NULL)
    {
      g_warning("Failed to set keepalive settings: %s\n", error->message);
      g_error_free(error);
    }

    break;
  case PROP_REMOTE_ADDRESS:
    g_assert(priv->status == INF_TCP_CONNECTION_CLOSED);
    if(priv->remote_address != NULL)
      inf_ip_address_free(priv->remote_address);
    priv->remote_address = (InfIpAddress*)g_value_dup_boxed(value);
    break;
  case PROP_REMOTE_PORT:
    g_assert(priv->status == INF_TCP_CONNECTION_CLOSED);
    priv->remote_port = g_value_get_uint(value);
    break;
  case PROP_DEVICE_INDEX:
    g_assert(priv->status == INF_TCP_CONNECTION_CLOSED);
    /* TODO: Verify that such a device exists */
    priv->device_index = g_value_get_uint(value);
    g_object_notify(G_OBJECT(object), "device-name");
    break;
  case PROP_DEVICE_NAME:
#ifdef G_OS_WIN32
    /* TODO: We can probably implement this using GetInterfaceInfo() */
    g_warning("The device-name property is not implemented on Win32");
#else
    g_assert(priv->status == INF_TCP_CONNECTION_CLOSED);
    device_string = g_value_get_string(value);
    if(device_string == NULL) priv->device_index = 0;

    new_index = if_nametoindex(device_string);
    if(new_index == 0)
    {
      g_warning(_("Interface `%s' does not exist"), device_string);
    }
    else
    {
      priv->device_index = new_index;
      g_object_notify(G_OBJECT(object), "device-index");
    }
#endif
    break;
  default:
    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
    break;
  }
}
Ejemplo n.º 13
0
static void
inf_tcp_connection_io(InfNativeSocket* socket,
                      InfIoEvent events,
                      gpointer user_data)
{
  InfTcpConnection* connection;
  InfTcpConnectionPrivate* priv;
  socklen_t len;
  int errcode;
  GError* error;

  connection = INF_TCP_CONNECTION(user_data);
  priv = INF_TCP_CONNECTION_PRIVATE(connection);
  g_object_ref(G_OBJECT(connection));

  g_assert(priv->status != INF_TCP_CONNECTION_CLOSED);

  if(events & INF_IO_ERROR)
  {
    len = sizeof(int);
#ifdef G_OS_WIN32
    getsockopt(priv->socket, SOL_SOCKET, SO_ERROR, (char*)&errcode, &len);
#else
    getsockopt(priv->socket, SOL_SOCKET, SO_ERROR, &errcode, &len);
#endif

    /* On Windows, we get INF_IO_ERROR on disconnection (at least with the
     * InfGtkIo, because FD_CLOSE is mapped to G_IO_HUP) with errcode
     * being 0. */
    /* TODO: Maybe we should change this by mapping G_IO_HUP to
     * INF_IO_INCOMING, hoping recv() does the right thing then. */
    if(errcode != 0)
    {
      error = NULL;
      inf_native_socket_make_error(errcode, &error);

      if(priv->status == INF_TCP_CONNECTION_CONNECTING)
      {
        inf_tcp_connection_connection_error(connection, error);
      }
      else
      {
        g_signal_emit(
          G_OBJECT(connection),
          tcp_connection_signals[ERROR_],
          0,
          error
        );
      }

      /* Error has been reported via signal emission, and there is nothing
       * else to do with it. */
      g_error_free(error);
    }
    else
    {
      inf_tcp_connection_close(connection);
    }
  }
  else
  {
    if(events & INF_IO_INCOMING)
    {
      inf_tcp_connection_io_incoming(connection);
    }

    /* It may happen that the above closes the connection and we received
     * events for both INCOMING & OUTGOING here. */
    if((priv->status != INF_TCP_CONNECTION_CLOSED) &&
       (events & INF_IO_OUTGOING))
    {
      inf_tcp_connection_io_outgoing(connection);
    }
  }

  g_object_unref(G_OBJECT(connection));
}
Ejemplo n.º 14
0
static void
inf_tcp_connection_io_outgoing(InfTcpConnection* connection)
{
  InfTcpConnectionPrivate* priv;

  socklen_t len;
  int errcode;

  gconstpointer data;
  guint data_len;

  priv = INF_TCP_CONNECTION_PRIVATE(connection);
  switch(priv->status)
  {
  case INF_TCP_CONNECTION_CONNECTING:
    len = sizeof(int);
#ifdef G_OS_WIN32
    getsockopt(priv->socket, SOL_SOCKET, SO_ERROR, (char*)&errcode, &len);
#else
    getsockopt(priv->socket, SOL_SOCKET, SO_ERROR, &errcode, &len);
#endif

    if(errcode == 0)
    {
      inf_tcp_connection_connected(connection);
    }
    else
    {
      inf_tcp_connection_system_error(connection, errcode);
    }

    break;
  case INF_TCP_CONNECTION_CONNECTED:
    g_assert(priv->back_pos < priv->front_pos);
    g_assert(priv->events & INF_IO_OUTGOING);

    data = priv->queue + priv->back_pos;
    data_len = priv->front_pos - priv->back_pos;
    if(inf_tcp_connection_send_real(connection, data, &data_len) == TRUE)
    {
      priv->back_pos += data_len;

      if(priv->front_pos == priv->back_pos)
      {
        /* sent everything */
        priv->front_pos = 0;
        priv->back_pos = 0;

        priv->events &= ~INF_IO_OUTGOING;

        inf_io_update_watch(priv->io, priv->watch, priv->events);
      }

      g_signal_emit(
        G_OBJECT(connection),
        tcp_connection_signals[SENT],
        0,
        data,
        data_len
      );
    }

    break;
  case INF_TCP_CONNECTION_CLOSED:
  default:
    g_assert_not_reached();
    break;
  }
}
Ejemplo n.º 15
0
/* internal insert routine */
static void
g_tree_insert_internal (GTree    *tree,
                        gpointer  key,
                        gpointer  value,
                        gboolean  replace)
{
    GTreeNode *node;
    GTreeNode *path[MAX_GTREE_HEIGHT];
    int idx;

    g_return_if_fail (tree != NULL);

    if (!tree->root)
    {
        tree->root = g_tree_node_new (key, value);
        tree->nnodes++;
        return;
    }

    idx = 0;
    path[idx++] = NULL;
    node = tree->root;

    while (1)
    {
        int cmp = tree->key_compare (key, node->key, tree->key_compare_data);

        if (cmp == 0)
        {
            if (tree->value_destroy_func)
                tree->value_destroy_func (node->value);

            node->value = value;

            if (replace)
            {
                if (tree->key_destroy_func)
                    tree->key_destroy_func (node->key);

                node->key = key;
            }
            else
            {
                /* free the passed key */
                if (tree->key_destroy_func)
                    tree->key_destroy_func (key);
            }

            return;
        }
        else if (cmp < 0)
        {
            if (node->left_child)
            {
                path[idx++] = node;
                node = node->left;
            }
            else
            {
                GTreeNode *child = g_tree_node_new (key, value);

                child->left = node->left;
                child->right = node;
                node->left = child;
                node->left_child = TRUE;
                node->balance -= 1;

                tree->nnodes++;

                break;
            }
        }
        else
        {
            if (node->right_child)
            {
                path[idx++] = node;
                node = node->right;
            }
            else
            {
                GTreeNode *child = g_tree_node_new (key, value);

                child->right = node->right;
                child->left = node;
                node->right = child;
                node->right_child = TRUE;
                node->balance += 1;

                tree->nnodes++;

                break;
            }
        }
    }

    /* restore balance. This is the goodness of a non-recursive
       implementation, when we are done with balancing we 'break'
       the loop and we are done. */
    while (1)
    {
        GTreeNode *bparent = path[--idx];
        gboolean left_node = (bparent && node == bparent->left);
        g_assert (!bparent || bparent->left == node || bparent->right == node);

        if (node->balance < -1 || node->balance > 1)
        {
            node = g_tree_node_balance (node);
            if (bparent == NULL)
                tree->root = node;
            else if (left_node)
                bparent->left = node;
            else
                bparent->right = node;
        }

        if (node->balance == 0 || bparent == NULL)
            break;

        if (left_node)
            bparent->balance -= 1;
        else
            bparent->balance += 1;

        node = bparent;
    }
}
Ejemplo n.º 16
0
void
nemo_menus_append_bookmark_to_menu (NemoWindow *window, 
					NemoBookmark *bookmark, 
					const char *parent_path,
					const char *parent_id,
					guint index_in_parent,
					GtkActionGroup *action_group,
					guint merge_id,
					GCallback refresh_callback,
					NemoBookmarkFailedCallback failed_callback)
{
	BookmarkHolder *bookmark_holder;
	char action_name[128];
	const char *name;
	char *path;
	GIcon *icon;
	GtkAction *action;
	GtkWidget *menuitem;

	g_assert (NEMO_IS_WINDOW (window));
	g_assert (NEMO_IS_BOOKMARK (bookmark));

	bookmark_holder = bookmark_holder_new (bookmark, window, refresh_callback, failed_callback);
	name = nemo_bookmark_get_name (bookmark);

	/* Create menu item with pixbuf */
	icon = nemo_bookmark_get_icon (bookmark);

	g_snprintf (action_name, sizeof (action_name), "%s%d", parent_id, index_in_parent);

	action = gtk_action_new (action_name,
				 name,
				 _("Go to the location specified by this bookmark"),
				 NULL);
	
	g_object_set_data_full (G_OBJECT (action), "menu-icon",
				icon,
				g_object_unref);

	g_signal_connect_data (action, "activate",
			       G_CALLBACK (activate_bookmark_in_menu_item),
			       bookmark_holder, 
			       bookmark_holder_free_cover, 0);

	gtk_action_group_add_action (action_group,
				     GTK_ACTION (action));

	g_object_unref (action);

	gtk_ui_manager_add_ui (window->details->ui_manager,
			       merge_id,
			       parent_path,
			       action_name,
			       action_name,
			       GTK_UI_MANAGER_MENUITEM,
			       FALSE);

	path = g_strdup_printf ("%s/%s", parent_path, action_name);
	menuitem = gtk_ui_manager_get_widget (window->details->ui_manager,
					      path);
	gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (menuitem),
						   TRUE);

	g_free (path);
}
Ejemplo n.º 17
0
/* internal remove routine */
static gboolean
g_tree_remove_internal (GTree         *tree,
                        gconstpointer  key,
                        gboolean       steal)
{
    GTreeNode *node, *parent, *balance;
    GTreeNode *path[MAX_GTREE_HEIGHT];
    int idx;
    gboolean left_node;

    g_return_val_if_fail (tree != NULL, FALSE);

    if (!tree->root)
        return FALSE;

    idx = 0;
    path[idx++] = NULL;
    node = tree->root;

    while (1)
    {
        int cmp = tree->key_compare (key, node->key, tree->key_compare_data);

        if (cmp == 0)
            break;
        else if (cmp < 0)
        {
            if (!node->left_child)
                return FALSE;

            path[idx++] = node;
            node = node->left;
        }
        else
        {
            if (!node->right_child)
                return FALSE;

            path[idx++] = node;
            node = node->right;
        }
    }

    /* the following code is almost equal to g_tree_remove_node,
       except that we do not have to call g_tree_node_parent. */
    balance = parent = path[--idx];
    g_assert (!parent || parent->left == node || parent->right == node);
    left_node = (parent && node == parent->left);

    if (!node->left_child)
    {
        if (!node->right_child)
        {
            if (!parent)
                tree->root = NULL;
            else if (left_node)
            {
                parent->left_child = FALSE;
                parent->left = node->left;
                parent->balance += 1;
            }
            else
            {
                parent->right_child = FALSE;
                parent->right = node->right;
                parent->balance -= 1;
            }
        }
        else /* node has a right child */
        {
            GTreeNode *tmp = g_tree_node_next (node);
            tmp->left = node->left;

            if (!parent)
                tree->root = node->right;
            else if (left_node)
            {
                parent->left = node->right;
                parent->balance += 1;
            }
            else
            {
                parent->right = node->right;
                parent->balance -= 1;
            }
        }
    }
    else /* node has a left child */
    {
        if (!node->right_child)
        {
            GTreeNode *tmp = g_tree_node_previous (node);
            tmp->right = node->right;

            if (parent == NULL)
                tree->root = node->left;
            else if (left_node)
            {
                parent->left = node->left;
                parent->balance += 1;
            }
            else
            {
                parent->right = node->left;
                parent->balance -= 1;
            }
        }
        else /* node has a both children (pant, pant!) */
        {
            GTreeNode *prev = node->left;
            GTreeNode *next = node->right;
            GTreeNode *nextp = node;
            int old_idx = idx + 1;
            idx++;

            /* path[idx] == parent */
            /* find the immediately next node (and its parent) */
            while (next->left_child)
            {
                path[++idx] = nextp = next;
                next = next->left;
            }

            path[old_idx] = next;
            balance = path[idx];

            /* remove 'next' from the tree */
            if (nextp != node)
            {
                if (next->right_child)
                    nextp->left = next->right;
                else
                    nextp->left_child = FALSE;
                nextp->balance += 1;

                next->right_child = TRUE;
                next->right = node->right;
            }
            else
                node->balance -= 1;

            /* set the prev to point to the right place */
            while (prev->right_child)
                prev = prev->right;
            prev->right = next;

            /* prepare 'next' to replace 'node' */
            next->left_child = TRUE;
            next->left = node->left;
            next->balance = node->balance;

            if (!parent)
                tree->root = next;
            else if (left_node)
                parent->left = next;
            else
                parent->right = next;
        }
    }

    /* restore balance */
    if (balance)
        while (1)
        {
            GTreeNode *bparent = path[--idx];
            g_assert (!bparent || bparent->left == balance || bparent->right == balance);
            left_node = (bparent && balance == bparent->left);

            if(balance->balance < -1 || balance->balance > 1)
            {
                balance = g_tree_node_balance (balance);
                if (!bparent)
                    tree->root = balance;
                else if (left_node)
                    bparent->left = balance;
                else
                    bparent->right = balance;
            }

            if (balance->balance != 0 || !bparent)
                break;

            if (left_node)
                bparent->balance += 1;
            else
                bparent->balance -= 1;

            balance = bparent;
        }

    if (!steal)
    {
        if (tree->key_destroy_func)
            tree->key_destroy_func (node->key);
        if (tree->value_destroy_func)
            tree->value_destroy_func (node->value);
    }

    g_slice_free (GTreeNode, node);

    tree->nnodes--;

    return TRUE;
}
Ejemplo n.º 18
0
/**
 * Initialize version string.
 */
G_GNUC_COLD void
version_init(void)
{
	time_t now;

	version_string = ostrdup_readonly(version_build_string());
	now = tm_time();

	{
		bool ok;
		const char *end;

		ok = version_parse(version_string, &our_version, &end);
		g_assert(ok);
		ok = version_ext_parse(end, &our_ext_version);
		g_assert(ok);
	}

	g_info("%s", version_string);

	version_stamp(version_string, &our_version);
	g_assert(our_version.timestamp != 0);

	{
		char buf[128];

		str_bprintf(buf, sizeof(buf),
			"%s/%s%s (%s)",
			product_get_name(), product_get_version(),
			product_get_build_full(), product_get_date());

		version_short_string = ostrdup_readonly(buf);
	}

	last_rel_version = our_version;			/* struct copy */
	last_dev_version = our_version;			/* struct copy */
	our_ext_version.version = our_version;	/* struct copy */

	/*
	 * The version code is a one-byte encoding of the year/month, since
	 * what matters is not much the version number as to the age of the
	 * servent...  The version code is transmitted in pongs via GGEP "VC".
	 */

	if (our_version.timestamp) {
		struct tm *tmp = localtime(&our_version.timestamp);
		version_code =
			(((tmp->tm_year + 1900 - 2000) & 0x0f) << 4) | (tmp->tm_mon + 1);
	} else
		version_code = 0;

	/*
	 * The property system is not up when this is called, but we need
	 * to set this variable correctly.
	 */

	if (
		tok_is_ancient(now) ||
		delta_time(now, our_version.timestamp) > VERSION_ANCIENT_WARN
	) {
		*deconstify_bool(&GNET_PROPERTY(ancient_version)) = TRUE;
	}
}
Ejemplo n.º 19
0
guint
panel_get_real_modifier_mask (guint mask)
{
	guint real_mask;
	Display *display;
	int i, min_keycode, max_keycode, keysyms_per_keycode;
	int max_keycodes_per_modifier;
	KeySym *keysyms_for_keycodes;
	XModifierKeymap *modifier_keymap;

	real_mask = mask & ((Mod5Mask << 1) - 1);

	/* Already real */
	if (mask == real_mask) {
		return mask;
	}

	display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());

	XDisplayKeycodes (display, &min_keycode, &max_keycode);
	keysyms_for_keycodes = XGetKeyboardMapping (display,
						    min_keycode,
						    max_keycode - min_keycode + 1,
						    &keysyms_per_keycode);

	modifier_keymap = XGetModifierMapping (display);
	max_keycodes_per_modifier = modifier_keymap->max_keypermod;

	/* Loop through all the modifiers and find out which "real"
	 * (Mod2..Mod5) modifiers Super, Hyper, and Meta are mapped to.
	 * Note, Mod1 is used by the Alt modifier */
	for (i = Mod2MapIndex * max_keycodes_per_modifier;
	     i < (Mod5MapIndex + 1) * max_keycodes_per_modifier;
	     i++) {
		int keycode;
		int j;
		KeySym *keysyms_for_keycode;
		int map_index;
		int map_mask;

		keycode = modifier_keymap->modifiermap[i];

		/* The array is sparse, there may be some
		 * empty entries.  Filter those out
		 * (along with any invalid entries) */
		if (keycode < min_keycode || keycode > max_keycode)
			continue;

		keysyms_for_keycode = keysyms_for_keycodes +
		                      (keycode - min_keycode) * keysyms_per_keycode;

		map_index = i / max_keycodes_per_modifier;

		g_assert (map_index <= Mod5MapIndex);

		map_mask = 1 << map_index;

		for (j = 0; j < keysyms_per_keycode; j++) {
			switch (keysyms_for_keycode[j]) {
				case XK_Super_L:
				case XK_Super_R:
					if (mask & GDK_SUPER_MASK)
						real_mask |= map_mask;
					break;
				case XK_Hyper_L:
				case XK_Hyper_R:
					if (mask & GDK_HYPER_MASK)
						real_mask |= map_mask;
					break;
				case XK_Meta_L:
				case XK_Meta_R:
					if (mask & GDK_META_MASK)
						real_mask |= map_mask;
					break;
				default:
					break;
			}
		}
	}

	XFreeModifiermap (modifier_keymap);
	XFree (keysyms_for_keycodes);

	return real_mask;
}
Ejemplo n.º 20
0
/**
 * Called after GUI initialized to warn them about an ancient version.
 * (over a year old).
 *
 * If the version being ran is not a stable one, warn after 60 days, otherwise
 * warn after a year.  If we're not "expired" yet but are approaching the
 * deadline, start to remind them. 
 */
void
version_ancient_warn(void)
{
	time_t now = tm_time();
	time_delta_t lifetime, remain, elapsed;
	time_t s;

	g_assert(our_version.timestamp != 0);	/* version_init() called */

	/*
	 * Must reset the property to FALSE so that if it changes and becomes
	 * TRUE, then the necessary GUI callbacks will get triggered.  Indeed,
	 * setting a property to its ancient value is not considered a change,
	 * and rightfully so!
	 */

	gnet_prop_set_boolean_val(PROP_ANCIENT_VERSION, FALSE);

	elapsed = delta_time(now, our_version.timestamp);

	if (elapsed > VERSION_ANCIENT_WARN || tok_is_ancient(now)) {
		static bool warned = FALSE;
		if (GNET_PROPERTY(version_debug)) {
			g_debug("VERSION our_version = %s (elapsed = %ld, token %s)",
				timestamp_to_string(our_version.timestamp),
				(long) elapsed, tok_is_ancient(now) ? "ancient" : "ok");
		}
		if (!warned) {
			g_warning("version of gtk-gnutella is too old, please upgrade!");
			warned = TRUE;
		}
        gnet_prop_set_boolean_val(PROP_ANCIENT_VERSION, TRUE);
		return;
	}

	/*
	 * Check whether we're nearing ancient version status, to warn them
	 * beforehand that the version will become old soon.
	 */

	lifetime = VERSION_ANCIENT_WARN;
	remain = delta_time(lifetime, elapsed);

	g_assert(remain >= 0);		/* None of the checks above have fired */

	/*
	 * Try to see whether the token will expire within the next
	 * VERSION_ANCIENT_REMIND secs, looking for the minimum cutoff date.
	 *
	 * Indeed, it is possible to emit new versions without issuing a
	 * new set of token keys, thereby constraining the lifetime of the
	 * version.  This is usually what happens for bug-fixing releases
	 * that do not introduce significant Gnutella features.
	 */

	s = time_advance(now, VERSION_ANCIENT_REMIND);
	for (/* NOTHING */; delta_time(s, now) > 0; s -= SECS_PER_DAY) {
		if (!tok_is_ancient(s))
			break;
	}

	remain = MIN(remain, delta_time(s, now));

	/*
	 * Let them know when version will expire soon...
	 */

	if (remain < VERSION_ANCIENT_REMIND) {
        gnet_prop_set_guint32_val(PROP_ANCIENT_VERSION_LEFT_DAYS,
			remain / SECS_PER_DAY);
	}
}
Ejemplo n.º 21
0
/* The shared state is not locked when prewait methods are called */
static void namedmutex_prewait (gpointer handle)
{
	/* If the mutex is not currently owned, do nothing and let the
	 * usual wait carry on.  If it is owned, check that the owner
	 * is still alive; if it isn't we override the previous owner
	 * and assume that process exited abnormally and failed to
	 * clean up.
	 */
	struct _WapiHandle_namedmutex *namedmutex_handle;
	gboolean ok;
	
	ok = _wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDMUTEX,
				  (gpointer *)&namedmutex_handle);
	if (ok == FALSE) {
		g_warning ("%s: error looking up named mutex handle %p",
			   __func__, handle);
		return;
	}
	
#ifdef DEBUG
	g_message ("%s: Checking ownership of named mutex handle %p", __func__,
		   handle);
#endif

	if (namedmutex_handle->recursion == 0) {
#ifdef DEBUG
		g_message ("%s: Named mutex handle %p not owned", __func__,
			   handle);
#endif
	} else if (namedmutex_handle->pid == _wapi_getpid ()) {
#ifdef DEBUG
		g_message ("%s: Named mutex handle %p owned by this process",
			   __func__, handle);
#endif
	} else {
		int thr_ret;
		gpointer proc_handle;
		
#ifdef DEBUG
		g_message ("%s: Named mutex handle %p owned by another process", __func__, handle);
#endif
		proc_handle = OpenProcess (0, 0, namedmutex_handle->pid);
		if (proc_handle == NULL) {
			/* Didn't find the process that this handle
			 * was owned by, overriding it
			 */
#ifdef DEBUG
			g_message ("%s: overriding old owner of named mutex handle %p", __func__, handle);
#endif
			thr_ret = _wapi_handle_lock_shared_handles ();
			g_assert (thr_ret == 0);

			namedmutex_handle->pid = 0;
			namedmutex_handle->tid = 0;
			namedmutex_handle->recursion = 0;

			_wapi_shared_handle_set_signal_state (handle, TRUE);
			_wapi_handle_unlock_shared_handles ();
		} else {
#ifdef DEBUG
			g_message ("%s: Found active pid %d for named mutex handle %p", __func__, namedmutex_handle->pid, handle);
#endif
		}
		if (proc_handle != NULL)
			CloseProcess (proc_handle);
	}
}
Ejemplo n.º 22
0
static void test_coroutine_simple(void)
{
    struct coroutine *self = coroutine_self();
    struct coroutine co = {
        .stack_size = 16 << 20,
        .entry = co_entry_42,
    };
    gpointer result;

    g_assert(coroutine_self_is_main());

    coroutine_init(&co);
    result = coroutine_yieldto(&co, GINT_TO_POINTER(42));
    g_assert_cmpint(GPOINTER_TO_INT(result), ==, 0x42);

    g_test_expect_message(G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "*!to->exited*");
    coroutine_yieldto(&co, GINT_TO_POINTER(42));
    g_test_assert_expected_messages();

    g_assert(self == coroutine_self());
    g_assert(coroutine_self_is_main());
}

static gpointer co_entry_two(gpointer data G_GNUC_UNUSED)
{
    struct coroutine *self = coroutine_self();
    struct coroutine co = {
        .stack_size = 16 << 20,
        .entry = co_entry_check_self,
    };

    g_assert(!coroutine_self_is_main());
    coroutine_init(&co);
    coroutine_yieldto(&co, &co);

    g_assert(self == coroutine_self());
    return NULL;
}

static void test_coroutine_two(void)
{
    struct coroutine *self = coroutine_self();
    struct coroutine co = {
        .stack_size = 16 << 20,
        .entry = co_entry_two,
    };

    coroutine_init(&co);
    coroutine_yieldto(&co, NULL);

    g_assert(self == coroutine_self());
}

static gpointer co_entry_yield(gpointer data)
{
    gpointer val;

    g_assert(data == NULL);
    val = coroutine_yield(GINT_TO_POINTER(1));
    g_assert_cmpint(GPOINTER_TO_INT(val), ==, 2);

    g_assert(!coroutine_self_is_main());

    val = coroutine_yield(GINT_TO_POINTER(3));
    g_assert_cmpint(GPOINTER_TO_INT(val), ==, 4);

    return NULL;
}

static void test_coroutine_yield(void)
{
    struct coroutine *self = coroutine_self();
    struct coroutine co = {
        .stack_size = 16 << 20,
        .entry = co_entry_yield,
    };
    gpointer val;

    coroutine_init(&co);
    val = coroutine_yieldto(&co, NULL);

    g_assert(self == coroutine_self());
    g_assert_cmpint(GPOINTER_TO_INT(val), ==, 1);

    val = coroutine_yieldto(&co, GINT_TO_POINTER(2));

    g_assert(self == coroutine_self());
    g_assert_cmpint(GPOINTER_TO_INT(val), ==, 3);

    val = coroutine_yieldto(&co, GINT_TO_POINTER(4));

    g_assert(self == coroutine_self());
    g_assert(val == NULL);

    g_test_expect_message(G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "*!to->exited*");
    coroutine_yieldto(&co, GINT_TO_POINTER(42));
    g_test_assert_expected_messages();
}

int main(int argc, char* argv[])
{
    g_test_init(&argc, &argv, NULL);

    g_test_add_func("/coroutine/simple", test_coroutine_simple);
    g_test_add_func("/coroutine/two", test_coroutine_two);
    g_test_add_func("/coroutine/yield", test_coroutine_yield);

    return g_test_run ();
}
Ejemplo n.º 23
0
static gboolean read_persistent_state(GAPersistentState *pstate,
                                      const gchar *path, gboolean frozen)
{
    GKeyFile *keyfile = NULL;
    GError *gerr = NULL;
    struct stat st;
    gboolean ret = true;

    g_assert(pstate);

    if (stat(path, &st) == -1) {
        /* it's okay if state file doesn't exist, but any other error
         * indicates a permissions issue or some other misconfiguration
         * that we likely won't be able to recover from.
         */
        if (errno != ENOENT) {
            g_critical("unable to access state file at path %s: %s",
                       path, strerror(errno));
            ret = false;
            goto out;
        }

        /* file doesn't exist. initialize state to default values and
         * attempt to save now. (we could wait till later when we have
         * modified state we need to commit, but if there's a problem,
         * such as a missing parent directory, we want to catch it now)
         *
         * there is a potential scenario where someone either managed to
         * update the agent from a version that didn't use a key store
         * while qemu-ga thought the filesystem was frozen, or
         * deleted the key store prior to issuing a fsfreeze, prior
         * to restarting the agent. in this case we go ahead and defer
         * initial creation till we actually have modified state to
         * write, otherwise fail to recover from freeze.
         */
        set_persistent_state_defaults(pstate);
        if (!frozen) {
            ret = write_persistent_state(pstate, path);
            if (!ret) {
                g_critical("unable to create state file at path %s", path);
                ret = false;
                goto out;
            }
        }
        ret = true;
        goto out;
    }

    keyfile = g_key_file_new();
    g_key_file_load_from_file(keyfile, path, 0, &gerr);
    if (gerr) {
        g_critical("error loading persistent state from path: %s, %s",
                   path, gerr->message);
        ret = false;
        goto out;
    }

    persistent_state_from_keyfile(pstate, keyfile);

out:
    if (keyfile) {
        g_key_file_free(keyfile);
    }
    if (gerr) {
        g_error_free(gerr);
    }

    return ret;
}
Ejemplo n.º 24
0
Archivo: gdl-dock.c Proyecto: vldm/gdl
/* Determines the best dock item to dock a new item with the given placement.
 * It traverses the dock tree and (based on the placement) tries to find
 * the best located item wrt to the placement. The approach is to find the
 * largest item on/around the placement side (for side placements) and to
 * find the largest item for center placement. In most situations, this is
 * what user wants and the heuristic should be therefore sufficient.
 */
static GdlDockItem*
gdl_dock_find_best_placement_item (GdlDockItem *dock_item,
                                   GdlDockPlacement placement,
                                   gint level /* for debugging */)
{
    GdlDockItem *ret_item = NULL;

    if (GDL_IS_DOCK_PANED (dock_item))
    {
        GtkOrientation orientation;
        GdlDockItem *dock_item_1, *dock_item_2;
        GList* children;

        children = gtk_container_get_children (GTK_CONTAINER (dock_item));

        g_assert (g_list_length (children) == 2);

        g_object_get (dock_item, "orientation", &orientation, NULL);
        if ((orientation == GTK_ORIENTATION_HORIZONTAL &&
             placement == GDL_DOCK_LEFT) ||
            (orientation == GTK_ORIENTATION_VERTICAL &&
             placement == GDL_DOCK_TOP)) {
            /* Return left or top pane widget */
            ret_item =
                gdl_dock_find_best_placement_item (GDL_DOCK_ITEM
                                                   (children->data),
                                                   placement, level + 1);
        } else if ((orientation == GTK_ORIENTATION_HORIZONTAL &&
                    placement == GDL_DOCK_RIGHT) ||
                   (orientation == GTK_ORIENTATION_VERTICAL &&
                    placement == GDL_DOCK_BOTTOM)) {
                        /* Return right or top pane widget */
            ret_item =
                gdl_dock_find_best_placement_item (GDL_DOCK_ITEM
                                                   (children->next->data),
                                                   placement, level + 1);
        } else {
            /* Evaluate which of the two sides is bigger */
            dock_item_1 =
                gdl_dock_find_best_placement_item (GDL_DOCK_ITEM
                                                   (children->data),
                                                   placement, level + 1);
            dock_item_2 =
                gdl_dock_find_best_placement_item (GDL_DOCK_ITEM
                                                   (children->next->data),
                                                   placement, level + 1);
            ret_item = gdl_dock_select_larger_item (dock_item_1,
                                                    dock_item_2,
                                                    placement, level);
        }
        g_list_free (children);
    }
    else if (GDL_IS_DOCK_ITEM (dock_item))
    {
        ret_item = dock_item;
    }
    else
    {
        /* should not be here */
        g_warning ("Should not reach here: %s:%d", __FUNCTION__, __LINE__);
    }
    return ret_item;
}
Ejemplo n.º 25
0
void
sgen_workers_join (void)
{
    State old_state, new_state;
    int i;

    if (!collection_needs_workers ())
        return;

    do {
        old_state = new_state = workers_state;
        g_assert (old_state.data.gc_in_progress);
        g_assert (!old_state.data.done_posted);

        new_state.data.gc_in_progress = 0;
    } while (!set_state (old_state, new_state));

    if (new_state.data.num_waiting == workers_num) {
        /*
         * All the workers have shut down but haven't posted
         * the done semaphore yet, or, if we come from below,
         * haven't done all their work yet.
         *
         * It's not a big deal to wake them up again - they'll
         * just do one iteration of their loop trying to find
         * something to do and then go back to waiting again.
         */
reawaken:
        workers_wake_up_all ();
    }
    MONO_SEM_WAIT (&workers_done_sem);

    old_state = new_state = workers_state;
    g_assert (old_state.data.num_waiting == workers_num);
    g_assert (old_state.data.done_posted);

    if (workers_job_queue_num_entries || !sgen_section_gray_queue_is_empty (&workers_distribute_gray_queue)) {
        /*
         * There's a small race condition that we avoid here.
         * It's possible that a worker thread runs out of
         * things to do, so it goes to sleep.  Right at that
         * moment a new job is enqueued, but the thread is
         * still registered as running.  Now the threads are
         * joined, and we wait for the semaphore.  Only at
         * this point does the worker go to sleep, and posts
         * the semaphore, because workers_gc_in_progress is
         * already FALSE.  The job is still in the queue,
         * though.
         *
         * Clear the done posted flag.
         */
        new_state.data.done_posted = 0;
        if (!set_state (old_state, new_state))
            g_assert_not_reached ();
        goto reawaken;
    }

    /* At this point all the workers have stopped. */

    workers_marking = FALSE;

    if (sgen_get_major_collector ()->reset_worker_data) {
        for (i = 0; i < workers_num; ++i)
            sgen_get_major_collector ()->reset_worker_data (workers_data [i].major_collector_data);
    }

    g_assert (workers_job_queue_num_entries == 0);
    g_assert (sgen_section_gray_queue_is_empty (&workers_distribute_gray_queue));
    for (i = 0; i < workers_num; ++i) {
        g_assert (!workers_data [i].stealable_stack_fill);
        g_assert (sgen_gray_object_queue_is_empty (&workers_data [i].private_gray_queue));
    }
}
Ejemplo n.º 26
0
static NMActStageReturn
act_stage2_config (NMDevice *device, NMDeviceStateReason *reason)
{
	NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device);
	DBusGConnection *bus;
	gboolean dun = FALSE;
	NMConnection *connection;

	connection = nm_device_get_connection (device);
	g_assert (connection);
	priv->bt_type = get_connection_bt_type (connection);
	if (priv->bt_type == NM_BT_CAPABILITY_NONE) {
		// FIXME: set a reason code
		return NM_ACT_STAGE_RETURN_FAILURE;
	}

	if (priv->bt_type == NM_BT_CAPABILITY_DUN && !priv->mm_running) {
		*reason = NM_DEVICE_STATE_REASON_MODEM_MANAGER_UNAVAILABLE;
		return NM_ACT_STAGE_RETURN_FAILURE;
	}

	if (priv->bt_type == NM_BT_CAPABILITY_DUN)
		dun = TRUE;
	else if (priv->bt_type == NM_BT_CAPABILITY_NAP)
		dun = FALSE;
	else
		g_assert_not_reached ();

	bus = nm_dbus_manager_get_connection (priv->dbus_mgr);
	priv->dev_proxy = dbus_g_proxy_new_for_name (bus,
	                                             BLUEZ_SERVICE,
	                                             nm_device_get_udi (device),
	                                             BLUEZ_DEVICE_INTERFACE);
	if (!priv->dev_proxy) {
		// FIXME: set a reason code
		return NM_ACT_STAGE_RETURN_FAILURE;
	}

	/* Watch for BT device property changes */
	dbus_g_object_register_marshaller (_nm_marshal_VOID__STRING_BOXED,
	                                   G_TYPE_NONE,
	                                   G_TYPE_STRING, G_TYPE_VALUE,
	                                   G_TYPE_INVALID);
	dbus_g_proxy_add_signal (priv->dev_proxy, "PropertyChanged",
	                         G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID);
	dbus_g_proxy_connect_signal (priv->dev_proxy, "PropertyChanged",
	                             G_CALLBACK (bluez_property_changed), device, NULL);

	priv->type_proxy = dbus_g_proxy_new_for_name (bus,
	                                              BLUEZ_SERVICE,
	                                              nm_device_get_udi (device),
	                                              dun ? BLUEZ_SERIAL_INTERFACE : BLUEZ_NETWORK_INTERFACE);
	if (!priv->type_proxy) {
		// FIXME: set a reason code
		return NM_ACT_STAGE_RETURN_FAILURE;
	}

	nm_log_dbg (LOGD_BT, "(%s): requesting connection to the device",
	            nm_device_get_iface (device));

	/* Connect to the BT device */
	dbus_g_proxy_begin_call_with_timeout (priv->type_proxy, "Connect",
	                                      bluez_connect_cb,
	                                      device,
	                                      NULL,
	                                      20000,
	                                      G_TYPE_STRING, dun ? BLUETOOTH_DUN_UUID : BLUETOOTH_NAP_UUID,
	                                      G_TYPE_INVALID);

	if (priv->timeout_id)
		g_source_remove (priv->timeout_id);
	priv->timeout_id = g_timeout_add_seconds (30, bt_connect_timeout, device);

	return NM_ACT_STAGE_RETURN_POSTPONE;
}
Ejemplo n.º 27
0
static GdkVisual *
gdk_gix_screen_get_rgba_visual (GdkScreen *screen)
{
  g_assert(system_visual != NULL);
  return (GdkVisual *) system_visual;
}
Ejemplo n.º 28
0
static gint
sxftd_init( SXFromTransInfo *sxfti )
{
    GtkWidget *w;
    const char *transName;
    gint pos;
    GList *schedule = NULL;
    time64 start_tt;
    struct tm *tmpTm;
    GDate date, nextDate;

    if ( ! sxfti->sx )
    {
        return -1;
    }
    if ( ! sxfti->trans )
    {
        return -2;
    }
    if ( xaccTransIsOpen( sxfti->trans ) )
    {
        return SXFTD_ERRNO_OPEN_XACTION;
    }

    /* Setup Widgets */
    {
        sxfti->ne_but = GTK_TOGGLE_BUTTON(gtk_builder_get_object(sxfti->builder, "never_end_button"));
        sxfti->ed_but = GTK_TOGGLE_BUTTON(gtk_builder_get_object(sxfti->builder, "end_on_date_button"));
        sxfti->oc_but = GTK_TOGGLE_BUTTON(gtk_builder_get_object(sxfti->builder, "n_occurrences_button"));
        sxfti->n_occurences = GTK_ENTRY(gtk_builder_get_object(sxfti->builder, "n_occurrences_entry"));
    }

    /* Get the name from the transaction, try that as the initial SX name. */
    transName = xaccTransGetDescription( sxfti->trans );
    xaccSchedXactionSetName( sxfti->sx, transName );

    sxfti->name = GTK_ENTRY(gtk_builder_get_object(sxfti->builder, "name_entry" ));
    pos = 0;
    gtk_editable_insert_text( GTK_EDITABLE(sxfti->name), transName,
                              (strlen(transName) * sizeof(char)), &pos );

    sxfti_attach_callbacks(sxfti);

    /* Setup the example calendar and related data structures. */
    {
        int num_marks = SXFTD_EXCAL_NUM_MONTHS * 31;

        w = GTK_WIDGET(gtk_builder_get_object(sxfti->builder, "ex_cal_frame" ));
        sxfti->dense_cal_model = gnc_dense_cal_store_new(num_marks);
        sxfti->example_cal = GNC_DENSE_CAL(gnc_dense_cal_new_with_model(GNC_DENSE_CAL_MODEL(sxfti->dense_cal_model)));
        g_object_ref_sink(sxfti->example_cal);

        g_assert(sxfti->example_cal);
        gnc_dense_cal_set_num_months( sxfti->example_cal, SXFTD_EXCAL_NUM_MONTHS );
        gnc_dense_cal_set_months_per_col( sxfti->example_cal, SXFTD_EXCAL_MONTHS_PER_COL );
        gtk_container_add( GTK_CONTAINER(w), GTK_WIDGET(sxfti->example_cal) );
    }

    /* Setup the start and end dates as GNCDateEdits */
    {
        GtkWidget *paramTable = GTK_WIDGET(gtk_builder_get_object(sxfti->builder, "param_table" ));
        sxfti->startDateGDE =
            GNC_DATE_EDIT( gnc_date_edit_new (gnc_time (NULL),
                                              FALSE, FALSE));
        gtk_table_attach( GTK_TABLE(paramTable),
                          GTK_WIDGET( sxfti->startDateGDE ),
                          1, 2, 2, 3,
                          (GTK_EXPAND | GTK_FILL),
                          GTK_FILL,
                          0, 0 );
        g_signal_connect( sxfti->startDateGDE, "date-changed",
                          G_CALLBACK( sxftd_update_excal_adapt ),
                          sxfti );
    }
    {
        GtkWidget *endDateBox = GTK_WIDGET(gtk_builder_get_object(sxfti->builder, "end_date_hbox" ));
        sxfti->endDateGDE =
            GNC_DATE_EDIT( gnc_date_edit_new (gnc_time (NULL),
                                              FALSE, FALSE));
        gtk_box_pack_start( GTK_BOX( endDateBox ),
                            GTK_WIDGET( sxfti->endDateGDE ),
                            TRUE, TRUE, 0 );
        g_signal_connect( sxfti->endDateGDE, "date-changed",
                          G_CALLBACK( sxftd_update_excal_adapt ),
                          sxfti );
    }

    /* Setup the initial start date for user display/confirmation */
    /* compute good initial date. */
    start_tt = xaccTransGetDate( sxfti->trans );
    gnc_gdate_set_time64( &date, start_tt );
    sxfti->freq_combo = GTK_COMBO_BOX(gtk_builder_get_object(sxfti->builder, "freq_combo_box"));
    gtk_combo_box_set_active(GTK_COMBO_BOX(sxfti->freq_combo), 0);
    g_signal_connect( sxfti->freq_combo, "changed",
                      G_CALLBACK(sxftd_freq_combo_changed),
                      sxfti );
    sxftd_update_schedule( sxfti, &date, &schedule);
    recurrenceListNextInstance(schedule, &date, &nextDate);
    recurrenceListFree(&schedule);
    start_tt = gnc_time64_get_day_start_gdate (&nextDate);
    gnc_date_edit_set_time( sxfti->startDateGDE, start_tt );

    g_signal_connect( GTK_OBJECT(sxfti->name), "destroy",
                      G_CALLBACK(sxftd_destroy),
                      sxfti );

    sxftd_update_example_cal( sxfti );

    return 0;
}
Ejemplo n.º 29
0
static void
terminal_profile_set_property (GObject *object,
                               guint prop_id,
                               const GValue *value,
                               GParamSpec *pspec)
{
	TerminalProfile *profile = TERMINAL_PROFILE (object);
	TerminalProfilePrivate *priv = profile->priv;
	GValue *prop_value;

	if (prop_id == 0 || prop_id >= LAST_PROP)
	{
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
		return;
	}

	prop_value = g_value_array_get_nth (priv->properties, prop_id);

	/* Preprocessing */
	switch (prop_id)
	{
#if 0
	case PROP_FONT:
	{
		PangoFontDescription *font_desc, *new_font_desc;

		font_desc = g_value_get_boxed (prop_value);
		new_font_desc = g_value_get_boxed (value);

		if (font_desc && new_font_desc)
		{
			/* Merge in case the new string isn't complete enough to load a font */
			pango_font_description_merge (font_desc, new_font_desc, TRUE);
			pango_font_description_free (new_font_desc);
			break;
		}

		/* fall-through */
	}
#endif
	default:
		g_value_copy (value, prop_value);
		break;
	}

	/* Postprocessing */
	switch (prop_id)
	{
	case PROP_NAME:
	{
		const char *name = g_value_get_string (value);

		g_assert (name != NULL);
		priv->profile_dir = g_strdup (name);
		if (priv->settings != NULL) {
			g_signal_handlers_disconnect_by_func (priv->settings,
							      G_CALLBACK(terminal_profile_gsettings_notify_cb),
							      profile);
			g_object_unref (priv->settings);
			priv->settings = g_settings_new_with_path (CONF_PROFILE_SCHEMA,
						g_strconcat (CONF_PROFILE_PREFIX, priv->profile_dir, "/", NULL));
			g_signal_connect (priv->settings,
					  g_strconcat("changed::", priv->profile_dir, "/", NULL),
						      G_CALLBACK(terminal_profile_gsettings_notify_cb),
					  profile);
		}
		break;
	}

	case PROP_BACKGROUND_IMAGE_FILE:
		/* Clear the cached image */
		g_value_set_object (g_value_array_get_nth (priv->properties, PROP_BACKGROUND_IMAGE), NULL);
		priv->background_load_failed = FALSE;
		g_object_notify (object, TERMINAL_PROFILE_BACKGROUND_IMAGE);
		break;

	default:
		break;
	}
}
Ejemplo n.º 30
0
/**
 * inf_tcp_connection_send:
 * @connection: A #InfTcpConnection with status %INF_TCP_CONNECTION_CONNECTED.
 * @data: (type guint8*) (array length=len): The data to send.
 * @len: Number of bytes to send.
 *
 * Sends data through the TCP connection. The data is not sent immediately,
 * but enqueued to a buffer and will be sent as soon as kernel space
 * becomes available. The "sent" signal will be emitted when data has
 * really been sent.
 **/
void
inf_tcp_connection_send(InfTcpConnection* connection,
                        gconstpointer data,
                        guint len)
{
  InfTcpConnectionPrivate* priv;
  gconstpointer sent_data;
  guint sent_len;

  g_return_if_fail(INF_IS_TCP_CONNECTION(connection));
  g_return_if_fail(len == 0 || data != NULL);

  priv = INF_TCP_CONNECTION_PRIVATE(connection);
  g_return_if_fail(priv->status == INF_TCP_CONNECTION_CONNECTED);

  g_object_ref(connection);

  /* Check whether we have data currently queued. If we have, then we need
   * to wait until that data has been sent before sending the new data. */
  if(priv->front_pos == priv->back_pos)
  {
    /* Must not be set, because otherwise we would need something to send,
     * but there is nothing in the queue. */
    g_assert(~priv->events & INF_IO_OUTGOING);

    /* Nothing in queue, send data directly. */
    sent_len = len;
    sent_data = data;

    if(inf_tcp_connection_send_real(connection, data, &sent_len) == TRUE)
    {
      data = (const char*)data + sent_len;
      len -= sent_len;
    }
    else
    {
      /* Sending failed. The error signal has been emitted. */
      /* Set len to zero so that we don't enqueue data. */
      len = 0;
      sent_len = 0;
    }
  }
  else
  {
    /* Nothing sent */
    sent_len = 0;
  }

  /* If we couldn't send all the data... */
  if(len > 0)
  {
    /* If we have not enough space for the new data, move queue data back
     * onto the beginning of the queue, if not already */
    if(priv->alloc - priv->front_pos < len && priv->back_pos > 0)
    {
      memmove(
        priv->queue,
        priv->queue + priv->back_pos,
        priv->front_pos - priv->back_pos
      );

      priv->front_pos -= priv->back_pos;
      priv->back_pos = 0;
    }

    /* Allocate more memory if there is still not enough space */
    if(priv->alloc - priv->front_pos < len)
    {
      /* Make sure we allocate enough */
      priv->alloc = priv->front_pos + len;

      /* Always allocate a multiple of 1024 */
      if(priv->alloc % 1024 != 0)
        priv->alloc = priv->alloc + (1024 - priv->alloc % 1024);

      priv->queue = g_realloc(priv->queue, priv->alloc);
    }

    memcpy(priv->queue + priv->front_pos, data, len);
    priv->front_pos += len;

    if(~priv->events & INF_IO_OUTGOING)
    {
      priv->events |= INF_IO_OUTGOING;
      inf_io_update_watch(priv->io, priv->watch, priv->events);
    }
  }

  if(sent_len > 0)
  {
    g_signal_emit(
      G_OBJECT(connection),
      tcp_connection_signals[SENT],
      0,
      sent_data,
      sent_len
    );
  }

  g_object_unref(connection);
}