[wing] wingnamedpipelistener: pass pipe settings in constructor instead of in set_named_pipe



commit fbdae67dace7fc153819f4fea5e3e3d09a8a5c36
Author: Silvio Lazzeretti <silviola amazon com>
Date:   Tue Aug 9 11:27:34 2022 +0200

    wingnamedpipelistener: pass pipe settings in constructor instead of in set_named_pipe

 tests/named-pipe.c           | 151 +++++++++----------
 wing/wingnamedpipelistener.c | 344 +++++++++++++++++++++++--------------------
 wing/wingnamedpipelistener.h |   7 +-
 3 files changed, 255 insertions(+), 247 deletions(-)
---
diff --git a/tests/named-pipe.c b/tests/named-pipe.c
index 0c229d5..df4422e 100644
--- a/tests/named-pipe.c
+++ b/tests/named-pipe.c
@@ -36,27 +36,23 @@ test_add_named_pipe (gconstpointer user_data)
   GError *error = NULL;
   TestData *test_data = (TestData *) user_data;
 
-  listener = wing_named_pipe_listener_new ();
-  wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
-
-  wing_named_pipe_listener_set_named_pipe (listener,
-                                           "\\\\.\\pipe\\gtest-good-named-pipe-name",
+  listener = wing_named_pipe_listener_new ("\\\\.\\pipe\\gtest-good-named-pipe-name",
                                            NULL,
                                            FALSE,
+                                           NULL,
                                            &error);
+  g_assert (listener != NULL);
   g_assert_no_error (error);
+
   g_object_unref (listener);
 
-  listener = wing_named_pipe_listener_new ();
-  wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
-  wing_named_pipe_listener_set_named_pipe (listener,
-                                           "\\\\.\\gtest-bad-named-pipe-name",
+  listener = wing_named_pipe_listener_new ("\\\\.\\gtest-bad-named-pipe-name",
                                            NULL,
                                            FALSE,
+                                           NULL,
                                            &error);
+  g_assert (listener == NULL);
   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
-
-  g_object_unref (listener);
 }
 
 static void
@@ -67,24 +63,20 @@ test_add_named_pipe_multiple_instances_no_protect (gconstpointer user_data)
   GError *error = NULL;
   TestData *test_data = (TestData *) user_data;
 
-  listener1 = wing_named_pipe_listener_new ();
-  wing_named_pipe_listener_set_use_iocp (listener1, test_data->use_iocp);
-
-  wing_named_pipe_listener_set_named_pipe (listener1,
-                                           "\\\\.\\pipe\\unprotected-named-pipe",
+  listener1 = wing_named_pipe_listener_new ("\\\\.\\pipe\\unprotected-named-pipe",
                                            NULL,
                                            FALSE,
+                                           NULL,
                                            &error);
+  g_assert (listener1 != NULL);
   g_assert_no_error (error);
 
-  listener2 = wing_named_pipe_listener_new ();
-  wing_named_pipe_listener_set_use_iocp (listener2, test_data->use_iocp);
-
-  wing_named_pipe_listener_set_named_pipe (listener2,
-                                           "\\\\.\\pipe\\unprotected-named-pipe",
+  listener2 = wing_named_pipe_listener_new ("\\\\.\\pipe\\unprotected-named-pipe",
                                            NULL,
                                            FALSE,
+                                           NULL,
                                            &error);
+  g_assert (listener2 != NULL);
   g_assert_no_error (error);
 
   g_object_unref (listener1);
@@ -99,28 +91,23 @@ test_add_named_pipe_multiple_instances_protected (gconstpointer user_data)
   GError *error = NULL;
   TestData *test_data = (TestData *) user_data;
 
-  listener1 = wing_named_pipe_listener_new ();
-  wing_named_pipe_listener_set_use_iocp (listener1, test_data->use_iocp);
-
-  wing_named_pipe_listener_set_named_pipe (listener1,
-                                           "\\\\.\\pipe\\protected-named-pipe",
+  listener1 = wing_named_pipe_listener_new ("\\\\.\\pipe\\protected-named-pipe",
                                            NULL,
                                            TRUE,
+                                           NULL,
                                            &error);
+  g_assert (listener1 != NULL);
   g_assert_no_error (error);
 
-  listener2 = wing_named_pipe_listener_new ();
-  wing_named_pipe_listener_set_use_iocp (listener2, test_data->use_iocp);
-
-  wing_named_pipe_listener_set_named_pipe (listener2,
-                                           "\\\\.\\pipe\\protected-named-pipe",
+  listener2 = wing_named_pipe_listener_new ("\\\\.\\pipe\\protected-named-pipe",
                                            NULL,
                                            TRUE,
+                                           NULL,
                                            &error);
+  g_assert (listener2 == NULL);
   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
 
   g_object_unref (listener1);
-  g_object_unref (listener2);
 }
 
 static void
@@ -167,16 +154,16 @@ test_connect_basic (gconstpointer user_data)
   GError *error = NULL;
   TestData *test_data = (TestData *) user_data;
 
-  listener = wing_named_pipe_listener_new ();
-  wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
-
-  wing_named_pipe_listener_set_named_pipe (listener,
-                                           "\\\\.\\pipe\\gtest-named-pipe-name",
+  listener = wing_named_pipe_listener_new ("\\\\.\\pipe\\gtest-named-pipe-name",
                                            NULL,
                                            FALSE,
+                                           NULL,
                                            &error);
+  g_assert (listener != NULL);
   g_assert_no_error (error);
 
+  wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
+
   wing_named_pipe_listener_accept_async (listener,
                                          NULL,
                                          accepted_cb,
@@ -210,16 +197,16 @@ test_connect_before_accept (gconstpointer user_data)
   GError *error = NULL;
   TestData *test_data = (TestData *) user_data;
 
-  listener = wing_named_pipe_listener_new ();
-  wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
-
-  wing_named_pipe_listener_set_named_pipe (listener,
-                                           "\\\\.\\pipe\\gtest-named-pipe-name",
+  listener = wing_named_pipe_listener_new ("\\\\.\\pipe\\gtest-named-pipe-name",
                                            NULL,
                                            FALSE,
+                                           NULL,
                                            &error);
+  g_assert (listener != NULL);
   g_assert_no_error (error);
 
+  wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
+
   client = wing_named_pipe_client_new ();
   wing_named_pipe_client_set_use_iocp (client, test_data->use_iocp);
 
@@ -252,16 +239,16 @@ test_connect_sync (gconstpointer user_data)
   GError *error = NULL;
   TestData *test_data = (TestData *) user_data;
 
-  listener = wing_named_pipe_listener_new ();
-  wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
-
-  wing_named_pipe_listener_set_named_pipe (listener,
-                                           "\\\\.\\pipe\\gtest-connect-sync",
+  listener = wing_named_pipe_listener_new ("\\\\.\\pipe\\gtest-connect-sync",
                                            NULL,
                                            FALSE,
+                                           NULL,
                                            &error);
+  g_assert (listener != NULL);
   g_assert_no_error (error);
 
+  wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
+
   client = wing_named_pipe_client_new ();
   wing_named_pipe_client_set_use_iocp (client, test_data->use_iocp);
 
@@ -337,16 +324,16 @@ test_accept_cancel (gconstpointer user_data)
   TestData *test_data = (TestData *) user_data;
   
   cancellable = g_cancellable_new ();
-  listener = wing_named_pipe_listener_new ();
-  wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
-
-  wing_named_pipe_listener_set_named_pipe (listener,
-                                           "\\\\.\\pipe\\gtest-named-pipe-name-cancel",
+  listener = wing_named_pipe_listener_new ("\\\\.\\pipe\\gtest-named-pipe-name-cancel",
                                            NULL,
                                            FALSE,
+                                           NULL,
                                            &error);
+  g_assert (listener != NULL);
   g_assert_no_error (error);
 
+  wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
+
   wing_named_pipe_listener_accept_async (listener,
                                          cancellable,
                                          accept_cancelled_cb,
@@ -374,16 +361,16 @@ test_connect_accept_cancel (gconstpointer user_data)
   TestData *test_data = (TestData *) user_data;
 
   cancellable = g_cancellable_new ();
-  listener = wing_named_pipe_listener_new ();
-  wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
-
-  wing_named_pipe_listener_set_named_pipe (listener,
-                                           "\\\\.\\pipe\\gtest-named-pipe-name-connect-then-cancel",
+  listener = wing_named_pipe_listener_new ("\\\\.\\pipe\\gtest-named-pipe-name-connect-then-cancel",
                                            NULL,
                                            FALSE,
+                                           NULL,
                                            &error);
+  g_assert (listener != NULL);
   g_assert_no_error (error);
 
+  wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
+
   wing_named_pipe_listener_accept_async (listener,
                                          cancellable,
                                          accepted_cb,
@@ -433,16 +420,16 @@ test_multi_client_basic (gconstpointer user_data)
   TestData *test_data = (TestData *) user_data;
 
   cancellable = g_cancellable_new ();
-  listener = wing_named_pipe_listener_new ();
-  wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
-
-  wing_named_pipe_listener_set_named_pipe (listener,
-                                           "\\\\.\\pipe\\gtest-named-pipe-name-connect-multi-client",
+  listener = wing_named_pipe_listener_new ("\\\\.\\pipe\\gtest-named-pipe-name-connect-multi-client",
                                            NULL,
                                            FALSE,
+                                           NULL,
                                            &error);
+  g_assert (listener != NULL);
   g_assert_no_error (error);
 
+  wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
+
   wing_named_pipe_listener_accept_async (listener,
                                          cancellable,
                                          accepted_cb,
@@ -718,16 +705,16 @@ test_read_write_basic (gconstpointer user_data)
   GError *error = NULL;
   TestData *test_data = (TestData *) user_data;
 
-  listener = wing_named_pipe_listener_new ();
-  wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
-
-  wing_named_pipe_listener_set_named_pipe (listener,
-                                           "\\\\.\\pipe\\gtest-named-pipe-name",
+  listener = wing_named_pipe_listener_new ("\\\\.\\pipe\\gtest-named-pipe-name",
                                            NULL,
                                            FALSE,
+                                           NULL,
                                            &error);
+  g_assert (listener != NULL);
   g_assert_no_error (error);
 
+  wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
+
   wing_named_pipe_listener_accept_async (listener,
                                          NULL,
                                          accepted_read_write_cb,
@@ -764,15 +751,15 @@ test_read_write_several_connections (gconstpointer user_data)
   GError *error = NULL;
   TestData *test_data = (TestData *) user_data;
 
-  listener = wing_named_pipe_listener_new ();
-  wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
-
-  wing_named_pipe_listener_set_named_pipe (listener,
-                                           "\\\\.\\pipe\\gtest-named-pipe-name-read-write-several",
+  listener = wing_named_pipe_listener_new ("\\\\.\\pipe\\gtest-named-pipe-name-read-write-several",
                                            NULL,
                                            FALSE,
+                                           NULL,
                                            &error);
+  g_assert (listener != NULL);
   g_assert_no_error (error);
+  
+  wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
 
   for (i = 0; i < MAX_ITERATIONS; i++)
     {
@@ -820,16 +807,16 @@ test_read_write_same_time_several_connections (gconstpointer user_data)
   GError *error = NULL;
   TestData *test_data = (TestData *) user_data;
 
-  listener = wing_named_pipe_listener_new ();
-  wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
-
-  wing_named_pipe_listener_set_named_pipe (listener,
-                                           "\\\\.\\pipe\\gtest-named-pipe-name-read-write-several",
+  listener = wing_named_pipe_listener_new ("\\\\.\\pipe\\gtest-named-pipe-name-read-write-several",
                                            NULL,
                                            FALSE,
+                                           NULL,
                                            &error);
+  g_assert (listener != NULL);
   g_assert_no_error (error);
 
+  wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
+
   client_conns = g_ptr_array_new_with_free_func (g_object_unref);
   server_conns = g_ptr_array_new_with_free_func (g_object_unref);
 
@@ -909,16 +896,16 @@ test_cancel_read (gconstpointer user_data)
   gchar data[256];
   TestData *test_data = (TestData *) user_data;
 
-  listener = wing_named_pipe_listener_new ();
-  wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
-
-  wing_named_pipe_listener_set_named_pipe (listener,
-                                           "\\\\.\\pipe\\gtest-named-pipe-name",
+  listener = wing_named_pipe_listener_new ("\\\\.\\pipe\\gtest-named-pipe-name",
                                            NULL,
                                            FALSE,
+                                           NULL,
                                            &error);
+  g_assert (listener != NULL);
   g_assert_no_error (error);
 
+  wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
+
   wing_named_pipe_listener_accept_async (listener,
                                          NULL,
                                          accepted_read_write_cb,
diff --git a/wing/wingnamedpipelistener.c b/wing/wingnamedpipelistener.c
index 5de48dd..2178b9d 100644
--- a/wing/wingnamedpipelistener.c
+++ b/wing/wingnamedpipelistener.c
@@ -29,65 +29,38 @@
 typedef struct
 {
   gchar *pipe_name;
-  gunichar2 *pipe_namew;
   gchar *security_descriptor;
+  gboolean protect_first_instance;
+
+  gunichar2 *pipe_namew;
   gunichar2 *security_descriptorw;
   HANDLE handle;
   OVERLAPPED overlapped;
   gboolean already_connected;
-} PipeData;
 
-typedef struct
-{
-  PipeData *named_pipe;
   gboolean use_iocp;
 } WingNamedPipeListenerPrivate;
 
 enum
 {
   PROP_0,
+  PROP_PIPE_NAME,
+  PROP_SECURITY_DESCRIPTOR,
+  PROP_PROTECT_FIRST_INSTANCE,
   PROP_USE_IOCP,
   LAST_PROP
 };
 
 static GParamSpec *props[LAST_PROP];
 
-G_DEFINE_TYPE_WITH_PRIVATE (WingNamedPipeListener, wing_named_pipe_listener, G_TYPE_OBJECT)
-
-static GQuark source_quark = 0;
-
-static PipeData *
-pipe_data_new (const gchar *pipe_name,
-               const gchar *security_descriptor)
-{
-  PipeData *data;
-
-  data = g_slice_new0 (PipeData);
-  data->pipe_name = g_strdup (pipe_name);
-  data->pipe_namew = g_utf8_to_utf16 (pipe_name, -1, NULL, NULL, NULL);
-  data->security_descriptor = g_strdup (security_descriptor);
-  data->security_descriptorw = security_descriptor != NULL ? g_utf8_to_utf16 (security_descriptor, -1, NULL, 
NULL, NULL) : NULL;
-  data->handle = INVALID_HANDLE_VALUE;
-  data->overlapped.hEvent = CreateEvent (NULL, /* default security attribute */
-                                         TRUE, /* manual-reset event */
-                                         TRUE, /* initial state = signaled */
-                                         NULL); /* unnamed event object */
+static void wing_named_pipe_listener_initable_iface_init (GInitableIface *iface);
 
-  return data;
-}
+G_DEFINE_TYPE_EXTENDED (WingNamedPipeListener, wing_named_pipe_listener, G_TYPE_OBJECT, 0,
+                        G_ADD_PRIVATE (WingNamedPipeListener)
+                        G_IMPLEMENT_INTERFACE(G_TYPE_INITABLE,
+                                              wing_named_pipe_listener_initable_iface_init))
 
-static void
-pipe_data_free (PipeData *data)
-{
-  g_free (data->pipe_name);
-  g_free (data->pipe_namew);
-  g_free (data->security_descriptor);
-  g_free (data->security_descriptorw);
-  if (data->handle != INVALID_HANDLE_VALUE)
-    CloseHandle (data->handle);
-  CloseHandle (data->overlapped.hEvent);
-  g_slice_free (PipeData, data);
-}
+static GQuark source_quark = 0;
 
 static void
 wing_named_pipe_listener_set_property (GObject      *object,
@@ -101,15 +74,27 @@ wing_named_pipe_listener_set_property (GObject      *object,
   priv = wing_named_pipe_listener_get_instance_private (listener);
 
   switch (prop_id)
-  {
-  case PROP_USE_IOCP:
-    priv->use_iocp = g_value_get_boolean (value);
-    break;
-
-  default:
-    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-    break;
-  }
+    {
+    case PROP_PIPE_NAME:
+      priv->pipe_name = g_value_dup_string (value);
+      break;
+
+    case PROP_SECURITY_DESCRIPTOR:
+      priv->security_descriptor = g_value_dup_string (value);
+      break;
+
+    case PROP_PROTECT_FIRST_INSTANCE:
+      priv->protect_first_instance = g_value_get_boolean (value);
+      break;
+
+    case PROP_USE_IOCP:
+      priv->use_iocp = g_value_get_boolean (value);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
 }
 
 static void
@@ -124,15 +109,27 @@ wing_named_pipe_listener_get_property (GObject    *object,
   priv = wing_named_pipe_listener_get_instance_private (listener);
 
   switch (prop_id)
-  {
-  case PROP_USE_IOCP:
+    {
+    case PROP_PIPE_NAME:
+      g_value_set_string (value, priv->pipe_name);
+      break;
+
+    case PROP_SECURITY_DESCRIPTOR:
+      g_value_set_string (value, priv->security_descriptor);
+      break;
+
+    case PROP_PROTECT_FIRST_INSTANCE:
+      g_value_set_boolean (value, priv->protect_first_instance);
+      break;
+
+    case PROP_USE_IOCP:
       g_value_set_boolean (value, priv->use_iocp);
       break;
 
-  default:
+    default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
-  }
+    }
 }
 
 static void
@@ -143,7 +140,12 @@ wing_named_pipe_listener_finalize (GObject *object)
 
   priv = wing_named_pipe_listener_get_instance_private (listener);
 
-  g_clear_pointer (&priv->named_pipe, pipe_data_free);
+  g_free (priv->pipe_name);
+  g_free (priv->pipe_namew);
+  g_free (priv->security_descriptor);
+  g_free (priv->security_descriptorw);
+  CloseHandle (priv->handle);
+  CloseHandle (priv->overlapped.hEvent);
 
   G_OBJECT_CLASS (wing_named_pipe_listener_parent_class)->finalize (object);
 }
@@ -159,6 +161,33 @@ wing_named_pipe_listener_class_init (WingNamedPipeListenerClass *klass)
 
   source_quark = g_quark_from_static_string ("g-win32-named-pipe-listener-source");
 
+  props[PROP_PIPE_NAME] =
+      g_param_spec_string ("pipe-name",
+                           "The name of the pipe",
+                           "The name of the pipe",
+                           NULL,
+                           G_PARAM_READWRITE |
+                           G_PARAM_CONSTRUCT_ONLY |
+                           G_PARAM_STATIC_STRINGS);
+
+  props[PROP_SECURITY_DESCRIPTOR] =
+      g_param_spec_string ("security-descriptor",
+                           "The security descriptor to apply to the pipe",
+                           "The security descriptor to apply to the pipe",
+                           NULL,
+                           G_PARAM_READWRITE |
+                           G_PARAM_CONSTRUCT_ONLY |
+                           G_PARAM_STATIC_STRINGS);
+
+  props[PROP_PROTECT_FIRST_INSTANCE] =
+      g_param_spec_boolean ("protect-first-instance",
+                           "Protect the first instance of the pipe",
+                           "Whether the creation of the pipe should fail if an instance of the pipe already 
exists",
+                           FALSE,
+                           G_PARAM_READWRITE |
+                           G_PARAM_CONSTRUCT_ONLY |
+                           G_PARAM_STATIC_STRINGS);
+
   /**
    * WingNamedPipeConnection:use-iocp:
    *
@@ -183,29 +212,58 @@ wing_named_pipe_listener_init (WingNamedPipeListener *listener)
 
 /**
  * wing_named_pipe_listener_new:
+ * @pipe_name: a name for the pipe.
+ * @security_descriptor: (allow-none): a security descriptor or %NULL.
+ * @protect_first_instance: if %TRUE, the pipe creation will fail if the pipe already exists
+ * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
+ * @error: #GError for error reporting, or %NULL to ignore.
  *
  * Creates a new #WingNamedPipeListener.
  *
+ * @security_descriptor must be of the format specified by Microsoft:
+ * https://msdn.microsoft.com/en-us/library/windows/desktop/aa379570(v=vs.85).aspx
+ * or set to %NULL to not set any security descriptor to the pipe.
+ *
+ * @security_descriptor must be of the format specified by Microsoft:
+ * https://msdn.microsoft.com/en-us/library/windows/desktop/aa379570(v=vs.85).aspx
+ * or set to %NULL to not set any security descriptor to the pipe.
+ * 
+ * @protect_first_instance will cause the first instance of the named pipe to be
+ * created with the FILE_FLAG_FIRST_PIPE_INSTANCE flag specified. This, in turn,
+ * will cause the creation of the pipe to fail if an instance of the pipe already
+ * exists. For more details see FILE_FLAG_FIRST_PIPE_INSTANCE details at:
+ * https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createnamedpipew
+ *
  * Returns: (transfer full): a new #WingNamedPipeListener.
  */
 WingNamedPipeListener *
-wing_named_pipe_listener_new (void)
+wing_named_pipe_listener_new (const gchar            *pipe_name,
+                              const gchar            *security_descriptor,
+                              gboolean                protect_first_instance,
+                              GCancellable           *cancellable,
+                              GError                **error)
 {
-  return g_object_new (WING_TYPE_NAMED_PIPE_LISTENER, NULL);
+  return g_initable_new (WING_TYPE_NAMED_PIPE_LISTENER,
+                         cancellable,
+                         error,
+                         "pipe-name", pipe_name,
+                         "security-descriptor", security_descriptor,
+                         "protect-first-instance", protect_first_instance,
+                         NULL);
 }
 
 static gboolean
-create_pipe_from_pipe_data (PipeData  *pipe_data,
-                            gboolean   protect_first_instance,
-                            GError   **error)
+create_pipe_from_pipe_data (WingNamedPipeListenerPrivate  *priv,
+                            gboolean                       protect_first_instance,
+                            GError                       **error)
 {
   SECURITY_ATTRIBUTES sa = { 0, };
 
-  if (pipe_data->security_descriptorw != NULL)
+  if (priv->security_descriptorw != NULL)
     {
       sa.nLength = sizeof (sa);
 
-      if (!ConvertStringSecurityDescriptorToSecurityDescriptorW (pipe_data->security_descriptorw,
+      if (!ConvertStringSecurityDescriptorToSecurityDescriptorW (priv->security_descriptorw,
                                                                  SDDL_REVISION_1,
                                                                  &sa.lpSecurityDescriptor,
                                                                  NULL))
@@ -217,7 +275,7 @@ create_pipe_from_pipe_data (PipeData  *pipe_data,
                        G_IO_ERROR,
                        g_io_error_from_win32_error (errsv),
                        "Could not convert the security descriptor '%s': %s",
-                       pipe_data->security_descriptor, emsg);
+                       priv->security_descriptor, emsg);
           g_free (emsg);
 
           return FALSE;
@@ -225,29 +283,29 @@ create_pipe_from_pipe_data (PipeData  *pipe_data,
     }
 
   /* Set event as signaled */
-  SetEvent(pipe_data->overlapped.hEvent);
+  SetEvent(priv->overlapped.hEvent);
 
   /* clear the flag if this was already connected */
-  pipe_data->already_connected = FALSE;
-
-  pipe_data->handle = CreateNamedPipeW (pipe_data->pipe_namew,
-                                        PIPE_ACCESS_DUPLEX |
-                                        FILE_FLAG_OVERLAPPED |
-                                        (protect_first_instance ? FILE_FLAG_FIRST_PIPE_INSTANCE : 0),
-                                        PIPE_TYPE_BYTE |
-                                        PIPE_READMODE_BYTE |
-                                        PIPE_WAIT |
-                                        PIPE_REJECT_REMOTE_CLIENTS,
-                                        PIPE_UNLIMITED_INSTANCES,
-                                        DEFAULT_PIPE_BUF_SIZE,
-                                        DEFAULT_PIPE_BUF_SIZE,
-                                        0,
-                                        pipe_data->security_descriptorw != NULL ? &sa : NULL);
+  priv->already_connected = FALSE;
+
+  priv->handle = CreateNamedPipeW (priv->pipe_namew,
+                                   PIPE_ACCESS_DUPLEX |
+                                   FILE_FLAG_OVERLAPPED |
+                                   (protect_first_instance ? FILE_FLAG_FIRST_PIPE_INSTANCE : 0),
+                                   PIPE_TYPE_BYTE |
+                                   PIPE_READMODE_BYTE |
+                                   PIPE_WAIT |
+                                   PIPE_REJECT_REMOTE_CLIENTS,
+                                   PIPE_UNLIMITED_INSTANCES,
+                                   DEFAULT_PIPE_BUF_SIZE,
+                                   DEFAULT_PIPE_BUF_SIZE,
+                                   0,
+                                   priv->security_descriptorw != NULL ? &sa : NULL);
 
   if (sa.lpSecurityDescriptor != NULL)
     LocalFree (sa.lpSecurityDescriptor);
 
-  if (pipe_data->handle == INVALID_HANDLE_VALUE)
+  if (priv->handle == INVALID_HANDLE_VALUE)
     {
       int errsv = GetLastError ();
       gchar *emsg = g_win32_error_message (errsv);
@@ -256,20 +314,20 @@ create_pipe_from_pipe_data (PipeData  *pipe_data,
                    G_IO_ERROR,
                    g_io_error_from_win32_error (errsv),
                    "Error creating named pipe '%s': %s",
-                   pipe_data->pipe_name, emsg);
+                   priv->pipe_name, emsg);
       g_free (emsg);
 
       return FALSE;
     }
 
-  if (!ConnectNamedPipe (pipe_data->handle, &pipe_data->overlapped))
+  if (!ConnectNamedPipe (priv->handle, &priv->overlapped))
     {
       switch (GetLastError ())
       {
       case ERROR_IO_PENDING:
         break;
       case ERROR_PIPE_CONNECTED:
-        pipe_data->already_connected = TRUE;
+        priv->already_connected = TRUE;
         break;
       default:
         {
@@ -279,7 +337,7 @@ create_pipe_from_pipe_data (PipeData  *pipe_data,
           g_set_error (error,
                        G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
                        "Failed to connect named pipe '%s': %s",
-                       pipe_data->pipe_name, emsg);
+                       priv->pipe_name, emsg);
           g_free (emsg);
 
           return FALSE;
@@ -290,61 +348,6 @@ create_pipe_from_pipe_data (PipeData  *pipe_data,
   return TRUE;
 }
 
-/**
- * wing_named_pipe_listener_set_named_pipe:
- * @listener: a #WingNamedPipeListener.
- * @pipe_name: a name for the pipe.
- * @security_descriptor: (allow-none): a security descriptor or %NULL.
- * @protect_first_instance: if %TRUE, the pipe creation will fail if the pipe already exists
- * @error: #GError for error reporting, or %NULL to ignore.
- *
- * Adds @named_pipe to the set of named pipes that we try to accept clients
- * from.
- *
- * @security_descriptor must be of the format specified by Microsoft:
- * https://msdn.microsoft.com/en-us/library/windows/desktop/aa379570(v=vs.85).aspx
- * or set to %NULL to not set any security descriptor to the pipe.
- *
- * @protect_first_instance will cause the first instance of the named pipe to be
- * created with the FILE_FLAG_FIRST_PIPE_INSTANCE flag specified. This, in turn,
- * will cause the creation of the pipe to fail if an instance of the pipe already
- * exists.For more details see FILE_FLAG_FIRST_PIPE_INSTANCE details at:
- * https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createnamedpipew
- *
- * @security_descriptor must be of the format specified by Microsoft:
- * https://msdn.microsoft.com/en-us/library/windows/desktop/aa379570(v=vs.85).aspx
- * or set to %NULL to not set any security descriptor to the pipe.
- *
- * Returns: %TRUE on success, %FALSE on error.
- */
-gboolean
-wing_named_pipe_listener_set_named_pipe (WingNamedPipeListener  *listener,
-                                         const gchar            *pipe_name,
-                                         const gchar            *security_descriptor,
-                                         gboolean                protect_first_instance,
-                                         GError                **error)
-{
-  WingNamedPipeListenerPrivate *priv;
-  PipeData *pipe_data;
-
-  g_return_val_if_fail (WING_IS_NAMED_PIPE_LISTENER (listener), FALSE);
-  g_return_val_if_fail (pipe_name != NULL, FALSE);
-
-  priv = wing_named_pipe_listener_get_instance_private (listener);
-
-  pipe_data = pipe_data_new (pipe_name, security_descriptor);
-  if (!create_pipe_from_pipe_data (pipe_data, protect_first_instance, error))
-    {
-      pipe_data_free (pipe_data);
-      return FALSE;
-    }
-
-  g_clear_pointer (&priv->named_pipe, pipe_data_free);
-  priv->named_pipe = pipe_data;
-
-  return TRUE;
-}
-
 static gboolean
 connect_ready (HANDLE   handle,
                gpointer user_data)
@@ -352,16 +355,12 @@ connect_ready (HANDLE   handle,
   GTask *task = user_data;
   WingNamedPipeListener *listener = g_task_get_source_object (task);
   WingNamedPipeListenerPrivate *priv;
-  PipeData *pipe_data = NULL;
   gulong cbret;
   guint i;
 
   priv = wing_named_pipe_listener_get_instance_private (listener);
 
-  pipe_data = priv->named_pipe;
-  g_return_val_if_fail (pipe_data != NULL, FALSE);
-
-  if (!GetOverlappedResult (pipe_data->handle, &pipe_data->overlapped, &cbret, FALSE))
+  if (!GetOverlappedResult (priv->handle, &priv->overlapped, &cbret, FALSE))
     {
       int errsv = GetLastError ();
       gchar *emsg = g_win32_error_message (errsv);
@@ -379,14 +378,14 @@ connect_ready (HANDLE   handle,
       GError *error = NULL;
 
       connection = g_object_new (WING_TYPE_NAMED_PIPE_CONNECTION,
-                                 "pipe-name", pipe_data->pipe_name,
-                                 "handle", pipe_data->handle,
+                                 "pipe-name", priv->pipe_name,
+                                 "handle", priv->handle,
                                  "close-handle", TRUE,
                                  "use-iocp", priv->use_iocp,
                                  NULL);
 
       /* Put another pipe to listen so more clients can already connect */
-      if (!create_pipe_from_pipe_data (pipe_data, FALSE, &error))
+      if (!create_pipe_from_pipe_data (priv, FALSE, &error))
         {
           g_object_unref (connection);
           g_task_return_error (task, error);
@@ -431,7 +430,6 @@ wing_named_pipe_listener_accept (WingNamedPipeListener  *listener,
                                  GError                **error)
 {
   WingNamedPipeListenerPrivate *priv;
-  PipeData *pipe_data = NULL;
   WingNamedPipeConnection *connection = NULL;
   gboolean success;
 
@@ -439,25 +437,22 @@ wing_named_pipe_listener_accept (WingNamedPipeListener  *listener,
 
   priv = wing_named_pipe_listener_get_instance_private (listener);
 
-  pipe_data = priv->named_pipe;
-  g_return_val_if_fail(pipe_data != NULL, NULL);
-
-  success = pipe_data->already_connected;
+  success = priv->already_connected;
 
   if (!success)
-    success = WaitForSingleObject (pipe_data->overlapped.hEvent, INFINITE) == WAIT_OBJECT_0;
+    success = WaitForSingleObject (priv->overlapped.hEvent, INFINITE) == WAIT_OBJECT_0;
 
   if (success)
     {
       connection = g_object_new (WING_TYPE_NAMED_PIPE_CONNECTION,
-                                 "pipe-name", pipe_data->pipe_name,
-                                 "handle", pipe_data->handle,
+                                 "pipe-name", priv->pipe_name,
+                                 "handle", priv->handle,
                                  "close-handle", TRUE,
                                  "use-iocp", priv->use_iocp,
                                  NULL);
 
       /* Put another pipe to listen so more clients can already connect */
-      if (!create_pipe_from_pipe_data (pipe_data, FALSE, error))
+      if (!create_pipe_from_pipe_data (priv, FALSE, error))
         g_clear_object (&connection);
     }
 
@@ -490,21 +485,20 @@ wing_named_pipe_listener_accept_async (WingNamedPipeListener *listener,
   task = g_task_new (listener, cancellable, callback, user_data);
 
   priv = wing_named_pipe_listener_get_instance_private (listener);
-  g_return_if_fail (priv->named_pipe != NULL);
 
-  if (priv->named_pipe->already_connected)
+  if (priv->already_connected)
     {
       WingNamedPipeConnection *connection;
       GError *error = NULL;
 
       connection = g_object_new (WING_TYPE_NAMED_PIPE_CONNECTION,
-                                 "pipe-name", priv->named_pipe->pipe_name,
-                                 "handle", priv->named_pipe->handle,
+                                 "pipe-name", priv->pipe_name,
+                                 "handle", priv->handle,
                                  "close-handle", TRUE,
                                  "use-iocp", priv->use_iocp,
                                  NULL);
 
-      if (!create_pipe_from_pipe_data (priv->named_pipe, FALSE, &error))
+      if (!create_pipe_from_pipe_data (priv, FALSE, &error))
         {
           g_object_unref (connection);
           g_task_return_error (task, error);
@@ -517,7 +511,7 @@ wing_named_pipe_listener_accept_async (WingNamedPipeListener *listener,
       return;
     }
 
-  source = wing_create_source (priv->named_pipe->overlapped.hEvent,
+  source = wing_create_source (priv->overlapped.hEvent,
                                G_IO_IN,
                                cancellable);
   g_source_set_callback (source,
@@ -564,4 +558,34 @@ wing_named_pipe_listener_set_use_iocp (WingNamedPipeListener *listener,
       priv->use_iocp = use_iocp;
       g_object_notify_by_pspec (G_OBJECT (listener), props[PROP_USE_IOCP]);
     }
+}
+
+static gboolean
+wing_named_pipe_listener_initable_init (GInitable     *initable,
+                                        GCancellable  *cancellable,
+                                        GError       **error)
+{
+  WingNamedPipeListener *listener;
+  WingNamedPipeListenerPrivate *priv;
+
+  g_return_val_if_fail (WING_IS_NAMED_PIPE_LISTENER (initable), FALSE);
+
+  listener = WING_NAMED_PIPE_LISTENER (initable);
+  priv = wing_named_pipe_listener_get_instance_private (listener);
+
+  priv->pipe_namew = g_utf8_to_utf16 (priv->pipe_name, -1, NULL, NULL, NULL);
+  priv->security_descriptorw = priv->security_descriptor != NULL ? g_utf8_to_utf16 
(priv->security_descriptor, -1, NULL, NULL, NULL) : NULL;
+  priv->handle = INVALID_HANDLE_VALUE;
+  priv->overlapped.hEvent = CreateEvent (NULL, /* default security attribute */
+                                         TRUE, /* manual-reset event */
+                                         TRUE, /* initial state = signaled */
+                                         NULL); /* unnamed event object */
+
+  return create_pipe_from_pipe_data (priv, priv->protect_first_instance, error);
+}
+
+static void
+wing_named_pipe_listener_initable_iface_init (GInitableIface *iface)
+{
+  iface->init = wing_named_pipe_listener_initable_init;
 }
\ No newline at end of file
diff --git a/wing/wingnamedpipelistener.h b/wing/wingnamedpipelistener.h
index fc41678..51e5680 100644
--- a/wing/wingnamedpipelistener.h
+++ b/wing/wingnamedpipelistener.h
@@ -52,13 +52,10 @@ WING_AVAILABLE_IN_ALL
 GType                     wing_named_pipe_listener_get_type       (void) G_GNUC_CONST;
 
 WING_AVAILABLE_IN_ALL
-WingNamedPipeListener    *wing_named_pipe_listener_new            (void);
-
-WING_AVAILABLE_IN_ALL
-gboolean                  wing_named_pipe_listener_set_named_pipe (WingNamedPipeListener  *listener,
-                                                                   const gchar            *pipe_name,
+WingNamedPipeListener    *wing_named_pipe_listener_new            (const gchar            *pipe_name,
                                                                    const gchar            
*security_descriptor,
                                                                    gboolean                
protect_first_instance,
+                                                                   GCancellable           *cancellable,
                                                                    GError                **error);
 
 WING_AVAILABLE_IN_ALL


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]