OSDN Git Service

* winsup.api/pthread/cancel1.c: New test. Port from pthreads-win32
authorduda <duda>
Thu, 4 Jul 2002 15:18:35 +0000 (15:18 +0000)
committerduda <duda>
Thu, 4 Jul 2002 15:18:35 +0000 (15:18 +0000)
project.
* winsup.api/pthread/cancel2.c: Ditto.
* winsup.api/pthread/cancel3.c: Ditto.
* winsup.api/pthread/cancel4.c: Ditto.
* winsup.api/pthread/cancel5.c: Ditto.

winsup/testsuite/ChangeLog
winsup/testsuite/winsup.api/pthread/cancel1.c [new file with mode: 0644]
winsup/testsuite/winsup.api/pthread/cancel2.c [new file with mode: 0644]
winsup/testsuite/winsup.api/pthread/cancel3.c [new file with mode: 0644]
winsup/testsuite/winsup.api/pthread/cancel4.c [new file with mode: 0644]
winsup/testsuite/winsup.api/pthread/cancel5.c [new file with mode: 0644]

index 5d9e335..297ba09 100644 (file)
@@ -1,3 +1,12 @@
+2002-07-04  Egor Duda  <deo@logos-m.ru>
+
+       * winsup.api/pthread/cancel1.c: New test. Port from pthreads-win32 
+       project.
+       * winsup.api/pthread/cancel2.c: Ditto.
+       * winsup.api/pthread/cancel3.c: Ditto.
+       * winsup.api/pthread/cancel4.c: Ditto.
+       * winsup.api/pthread/cancel5.c: Ditto.
+
 2002-07-03  Christopher Faylor  <cgf@redhat.com>
 
        * Makefile.in: Eliminate unneeded Makefile recreation rule.
diff --git a/winsup/testsuite/winsup.api/pthread/cancel1.c b/winsup/testsuite/winsup.api/pthread/cancel1.c
new file mode 100644 (file)
index 0000000..96ae390
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * File: cancel1.c
+ *
+ * Test Synopsis: Test setting cancel state and cancel type.
+ * - 
+ *
+ * Test Method (Validation or Falsification):
+ * - 
+ *
+ * Requirements Tested:
+ * - pthread_setcancelstate function
+ * - pthread_setcanceltype function
+ *
+ * Features Tested:
+ * - 
+ *
+ * Cases Tested:
+ * - 
+ *
+ * Description:
+ * - 
+ *
+ * Environment:
+ * - 
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * - pthread_create, pthread_self work.
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+
+/*
+ * Create NUMTHREADS threads in addition to the Main thread.
+ */
+enum {
+  NUMTHREADS = 10
+};
+
+typedef struct bag_t_ bag_t;
+struct bag_t_ {
+  int threadnum;
+  int started;
+  /* Add more per-thread state variables here */
+};
+
+static bag_t threadbag[NUMTHREADS + 1];
+
+void *
+mythread(void * arg)
+{
+  bag_t * bag = (bag_t *) arg;
+
+  assert(bag == &threadbag[bag->threadnum]);
+  assert(bag->started == 0);
+  bag->started = 1;
+
+  /* ... */
+  {
+    int oldstate;
+    int oldtype;
+
+    assert(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate) == 0);
+    assert(oldstate == PTHREAD_CANCEL_ENABLE); /* Check default */
+    assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0);
+    assert(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL) == 0);
+    assert(pthread_setcancelstate(oldstate, &oldstate) == 0);
+    assert(oldstate == PTHREAD_CANCEL_DISABLE); /* Check setting */
+
+    assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype) == 0);
+    assert(oldtype == PTHREAD_CANCEL_DEFERRED); /* Check default */
+    assert(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) == 0);
+    assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0);
+    assert(pthread_setcanceltype(oldtype, &oldtype) == 0);
+    assert(oldtype == PTHREAD_CANCEL_ASYNCHRONOUS); /* Check setting */
+  }
+
+  return 0;
+}
+
+int
+main()
+{
+  int failed = 0;
+  int i;
+  pthread_t t[NUMTHREADS + 1];
+
+  assert((t[0] = pthread_self()) != NULL);
+
+  for (i = 1; i <= NUMTHREADS; i++)
+    {
+      threadbag[i].started = 0;
+      threadbag[i].threadnum = i;
+      assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0);
+    }
+
+  /*
+   * Code to control or munipulate child threads should probably go here.
+   */
+
+  /*
+   * Give threads time to run.
+   */
+  Sleep(NUMTHREADS * 1000);
+
+  /*
+   * Standard check that all threads started.
+   */
+  for (i = 1; i <= NUMTHREADS; i++)
+    { 
+      failed = !threadbag[i].started;
+
+      if (failed)
+       {
+         fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
+       }
+    }
+
+  assert(!failed);
+
+  /*
+   * Check any results here. Set "failed" and only print ouput on failure.
+   */
+  for (i = 1; i <= NUMTHREADS; i++)
+    { 
+      /* ... */
+    }
+
+  assert(!failed);
+
+  /*
+   * Success.
+   */
+  return 0;
+}
diff --git a/winsup/testsuite/winsup.api/pthread/cancel2.c b/winsup/testsuite/winsup.api/pthread/cancel2.c
new file mode 100644 (file)
index 0000000..2d99c34
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * File: cancel2.c
+ *
+ * Test Synopsis: Test SEH or C++ cancel exception handling within
+ * application exception blocks.
+ *
+ * Test Method (Validation or Falsification):
+ * - 
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * - 
+ *
+ * Cases Tested:
+ * - 
+ *
+ * Description:
+ * - 
+ *
+ * Environment:
+ * - 
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
+ *   pthread_testcancel, pthread_cancel, pthread_join
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+
+/*
+ * Create NUMTHREADS threads in addition to the Main thread.
+ */
+enum {
+  NUMTHREADS = 10
+};
+
+typedef struct bag_t_ bag_t;
+struct bag_t_ {
+  int threadnum;
+  int started;
+  /* Add more per-thread state variables here */
+};
+
+static bag_t threadbag[NUMTHREADS + 1];
+
+static pthread_mutex_t waitLock = PTHREAD_MUTEX_INITIALIZER;
+
+void *
+mythread(void * arg)
+{
+  int result = 0;
+  bag_t * bag = (bag_t *) arg;
+
+  assert(bag == &threadbag[bag->threadnum]);
+  assert(bag->started == 0);
+  bag->started = 1;
+
+  /* Set to known state and type */
+
+  assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0);
+
+  switch (bag->threadnum % 2)
+    {
+    case 0:
+      assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0);
+      result = 0;
+      break;
+    case 1:
+      assert(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) == 0);
+      result = 1;
+      break;
+    }
+
+  /* Wait for go from main */
+  assert(pthread_mutex_lock(&waitLock) == 0);
+  assert(pthread_mutex_unlock(&waitLock) == 0);
+  sched_yield();
+
+  for (;;)
+    {    
+      pthread_testcancel();
+    }
+
+  return (void *) result;
+}
+
+int
+main()
+{
+  int failed = 0;
+  int i;
+  pthread_t t[NUMTHREADS + 1];
+
+  assert((t[0] = pthread_self()) != NULL);
+  assert(pthread_mutex_lock(&waitLock) == 0);
+
+  for (i = 1; i <= NUMTHREADS; i++)
+    {
+      threadbag[i].started = 0;
+      threadbag[i].threadnum = i;
+      assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0);
+    }
+
+  /*
+   * Code to control or munipulate child threads should probably go here.
+   */
+  Sleep(500);
+
+  assert(pthread_mutex_unlock(&waitLock) == 0);
+
+  Sleep(500);
+
+  for (i = 1; i <= NUMTHREADS; i++)
+    {
+      assert(pthread_cancel(t[i]) == 0);
+    }
+
+  /*
+   * Give threads time to run.
+   */
+  Sleep(NUMTHREADS * 100);
+
+  /*
+   * Standard check that all threads started.
+   */
+  for (i = 1; i <= NUMTHREADS; i++)
+    { 
+      if (!threadbag[i].started)
+       {
+         failed |= !threadbag[i].started;
+         fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
+       }
+    }
+
+  assert(!failed);
+
+  /*
+   * Check any results here. Set "failed" and only print output on failure.
+   */
+  failed = 0;
+  for (i = 1; i <= NUMTHREADS; i++)
+    {
+      int fail = 0;
+      int result = 0;
+
+      assert(pthread_join(t[i], (void **) &result) == 0);
+      fail = (result != (int) PTHREAD_CANCELED);
+      if (fail)
+       {
+         fprintf(stderr, "Thread %d: started %d: location %d: cancel type %s\n",
+                 i,
+                 threadbag[i].started,
+                 result,
+                 ((result % 2) == 0) ? "ASYNCHRONOUS" : "DEFERRED");
+       }
+      failed |= fail;
+    }
+
+  assert(!failed);
+
+  /*
+   * Success.
+   */
+  return 0;
+}
+
diff --git a/winsup/testsuite/winsup.api/pthread/cancel3.c b/winsup/testsuite/winsup.api/pthread/cancel3.c
new file mode 100644 (file)
index 0000000..3ac03e4
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * File: cancel3.c
+ *
+ * Test Synopsis: Test asynchronous cancelation.
+ *
+ * Test Method (Validation or Falsification):
+ * - 
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * - 
+ *
+ * Cases Tested:
+ * - 
+ *
+ * Description:
+ * - 
+ *
+ * Environment:
+ * - 
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
+ *   pthread_testcancel, pthread_cancel, pthread_join
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+
+/*
+ * Create NUMTHREADS threads in addition to the Main thread.
+ */
+enum {
+  NUMTHREADS = 10
+};
+
+typedef struct bag_t_ bag_t;
+struct bag_t_ {
+  int threadnum;
+  int started;
+  /* Add more per-thread state variables here */
+  int count;
+};
+
+static bag_t threadbag[NUMTHREADS + 1];
+
+void *
+mythread(void * arg)
+{
+  int result = ((int)PTHREAD_CANCELED + 1);
+  bag_t * bag = (bag_t *) arg;
+
+  assert(bag == &threadbag[bag->threadnum]);
+  assert(bag->started == 0);
+  bag->started = 1;
+
+  /* Set to known state and type */
+
+  assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0);
+
+  assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0);
+
+  /*
+   * We wait up to 10 seconds, waking every 0.1 seconds,
+   * for a cancelation to be applied to us.
+   */
+  for (bag->count = 0; bag->count < 100; bag->count++)
+    Sleep(100);
+
+  return (void *) result;
+}
+
+int
+main()
+{
+  int failed = 0;
+  int i;
+  pthread_t t[NUMTHREADS + 1];
+
+  assert((t[0] = pthread_self()) != NULL);
+
+  for (i = 1; i <= NUMTHREADS; i++)
+    {
+      threadbag[i].started = 0;
+      threadbag[i].threadnum = i;
+      assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0);
+    }
+
+  /*
+   * Code to control or munipulate child threads should probably go here.
+   */
+  Sleep(500);
+
+  for (i = 1; i <= NUMTHREADS; i++)
+    {
+      assert(pthread_cancel(t[i]) == 0);
+    }
+
+  /*
+   * Give threads time to run.
+   */
+  Sleep(NUMTHREADS * 100);
+
+  /*
+   * Standard check that all threads started.
+   */
+  for (i = 1; i <= NUMTHREADS; i++)
+    { 
+      if (!threadbag[i].started)
+       {
+         failed |= !threadbag[i].started;
+         fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
+       }
+    }
+
+  assert(!failed);
+
+  /*
+   * Check any results here. Set "failed" and only print output on failure.
+   */
+  failed = 0;
+  for (i = 1; i <= NUMTHREADS; i++)
+    {
+      int fail = 0;
+      int result = 0;
+
+      /*
+       * The thread does not contain any cancelation points, so
+       * a return value of PTHREAD_CANCELED confirms that async
+       * cancelation succeeded.
+       */
+      assert(pthread_join(t[i], (void **) &result) == 0);
+
+      fail = (result != (int) PTHREAD_CANCELED);
+
+      if (fail)
+       {
+         fprintf(stderr, "Thread %d: started %d: count %d\n",
+                 i,
+                 threadbag[i].started,
+                 threadbag[i].count);
+       }
+      failed = (failed || fail);
+    }
+
+  assert(!failed);
+
+  /*
+   * Success.
+   */
+  return 0;
+}
diff --git a/winsup/testsuite/winsup.api/pthread/cancel4.c b/winsup/testsuite/winsup.api/pthread/cancel4.c
new file mode 100644 (file)
index 0000000..d6b2ffa
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * File: cancel4.c
+ *
+ * Test Synopsis: Test cancelation does not occur in deferred
+ *                cancelation threads with no cancelation points.
+ *
+ * Test Method (Validation or Falsification):
+ * - 
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * - 
+ *
+ * Cases Tested:
+ * - 
+ *
+ * Description:
+ * - 
+ *
+ * Environment:
+ * - 
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * - pthread_create
+ *   pthread_self
+ *   pthread_cancel
+ *   pthread_join
+ *   pthread_setcancelstate
+ *   pthread_setcanceltype
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+
+/*
+ * Create NUMTHREADS threads in addition to the Main thread.
+ */
+enum {
+  NUMTHREADS = 10
+};
+
+typedef struct bag_t_ bag_t;
+struct bag_t_ {
+  int threadnum;
+  int started;
+  /* Add more per-thread state variables here */
+  int count;
+};
+
+static bag_t threadbag[NUMTHREADS + 1];
+
+void *
+mythread(void * arg)
+{
+  int result = ((int)PTHREAD_CANCELED + 1);
+  bag_t * bag = (bag_t *) arg;
+
+  assert(bag == &threadbag[bag->threadnum]);
+  assert(bag->started == 0);
+  bag->started = 1;
+
+  /* Set to known state and type */
+
+  assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0);
+
+  assert(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) == 0);
+
+  /*
+   * We wait up to 10 seconds, waking every 0.1 seconds,
+   * for a cancelation to be applied to us.
+   */
+  for (bag->count = 0; bag->count < 100; bag->count++)
+    Sleep(100);
+
+  return (void *) result;
+}
+
+int
+main()
+{
+  int failed = 0;
+  int i;
+  pthread_t t[NUMTHREADS + 1];
+
+  assert((t[0] = pthread_self()) != NULL);
+
+  for (i = 1; i <= NUMTHREADS; i++)
+    {
+      threadbag[i].started = 0;
+      threadbag[i].threadnum = i;
+      assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0);
+    }
+
+  /*
+   * Code to control or munipulate child threads should probably go here.
+   */
+  Sleep(500);
+
+  for (i = 1; i <= NUMTHREADS; i++)
+    {
+      assert(pthread_cancel(t[i]) == 0);
+    }
+
+  /*
+   * Give threads time to run.
+   */
+  Sleep(NUMTHREADS * 100);
+
+  /*
+   * Standard check that all threads started.
+   */
+  for (i = 1; i <= NUMTHREADS; i++)
+    { 
+      if (!threadbag[i].started)
+       {
+         failed |= !threadbag[i].started;
+         fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
+       }
+    }
+
+  assert(!failed);
+
+  /*
+   * Check any results here. Set "failed" and only print output on failure.
+   */
+  failed = 0;
+  for (i = 1; i <= NUMTHREADS; i++)
+    {
+      int fail = 0;
+      int result = 0;
+
+      /*
+       * The thread does not contain any cancelation points, so
+       * a return value of PTHREAD_CANCELED indicates that async
+       * cancelation occurred.
+       */
+      assert(pthread_join(t[i], (void **) &result) == 0);
+
+      fail = (result == (int) PTHREAD_CANCELED);
+
+      if (fail)
+       {
+         fprintf(stderr, "Thread %d: started %d: count %d\n",
+                 i,
+                 threadbag[i].started,
+                 threadbag[i].count);
+       }
+      failed = (failed || fail);
+    }
+
+  assert(!failed);
+
+  /*
+   * Success.
+   */
+  return 0;
+}
+
diff --git a/winsup/testsuite/winsup.api/pthread/cancel5.c b/winsup/testsuite/winsup.api/pthread/cancel5.c
new file mode 100644 (file)
index 0000000..9dd5795
--- /dev/null
@@ -0,0 +1,165 @@
+/*\r
+ * File: cancel5.c\r
+ *\r
+ * Test Synopsis: Test calling pthread_cancel from the main thread\r
+ *                without calling pthread_self() in main.\r
+ *\r
+ * Test Method (Validation or Falsification):\r
+ * - \r
+ *\r
+ * Requirements Tested:\r
+ * -\r
+ *\r
+ * Features Tested:\r
+ * - \r
+ *\r
+ * Cases Tested:\r
+ * - \r
+ *\r
+ * Description:\r
+ * - \r
+ *\r
+ * Environment:\r
+ * - \r
+ *\r
+ * Input:\r
+ * - None.\r
+ *\r
+ * Output:\r
+ * - File name, Line number, and failed expression on failure.\r
+ * - No output on success.\r
+ *\r
+ * Assumptions:\r
+ * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock\r
+ *   pthread_testcancel, pthread_cancel, pthread_join\r
+ *\r
+ * Pass Criteria:\r
+ * - Process returns zero exit status.\r
+ *\r
+ * Fail Criteria:\r
+ * - Process returns non-zero exit status.\r
+ */\r
+\r
+#include "test.h"\r
+\r
+/*\r
+ * Create NUMTHREADS threads in addition to the Main thread.\r
+ */\r
+enum {\r
+  NUMTHREADS = 10\r
+};\r
+\r
+typedef struct bag_t_ bag_t;\r
+struct bag_t_ {\r
+  int threadnum;\r
+  int started;\r
+  /* Add more per-thread state variables here */\r
+  int count;\r
+};\r
+\r
+static bag_t threadbag[NUMTHREADS + 1];\r
+\r
+void *\r
+mythread(void * arg)\r
+{\r
+  int result = ((int)PTHREAD_CANCELED + 1);\r
+  bag_t * bag = (bag_t *) arg;\r
+\r
+  assert(bag == &threadbag[bag->threadnum]);\r
+  assert(bag->started == 0);\r
+  bag->started = 1;\r
+\r
+  /* Set to known state and type */\r
+\r
+  assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0);\r
+\r
+  assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0);\r
+\r
+  /*\r
+   * We wait up to 10 seconds, waking every 0.1 seconds,\r
+   * for a cancelation to be applied to us.\r
+   */\r
+  for (bag->count = 0; bag->count < 100; bag->count++)\r
+    Sleep(100);\r
+\r
+  return (void *) result;\r
+}\r
+\r
+int\r
+main()\r
+{\r
+  int failed = 0;\r
+  int i;\r
+  pthread_t t[NUMTHREADS + 1];\r
+\r
+  for (i = 1; i <= NUMTHREADS; i++)\r
+    {\r
+      threadbag[i].started = 0;\r
+      threadbag[i].threadnum = i;\r
+      assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0);\r
+    }\r
+\r
+  /*\r
+   * Code to control or munipulate child threads should probably go here.\r
+   */\r
+  Sleep(500);\r
+\r
+  for (i = 1; i <= NUMTHREADS; i++)\r
+    {\r
+      assert(pthread_cancel(t[i]) == 0);\r
+    }\r
+\r
+  /*\r
+   * Give threads time to run.\r
+   */\r
+  Sleep(NUMTHREADS * 100);\r
+\r
+  /*\r
+   * Standard check that all threads started.\r
+   */\r
+  for (i = 1; i <= NUMTHREADS; i++)\r
+    { \r
+      if (!threadbag[i].started)\r
+       {\r
+         failed |= !threadbag[i].started;\r
+         fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);\r
+       }\r
+    }\r
+\r
+  assert(!failed);\r
+\r
+  /*\r
+   * Check any results here. Set "failed" and only print output on failure.\r
+   */\r
+  failed = 0;\r
+  for (i = 1; i <= NUMTHREADS; i++)\r
+    {\r
+      int fail = 0;\r
+      int result = 0;\r
+\r
+      /*\r
+       * The thread does not contain any cancelation points, so\r
+       * a return value of PTHREAD_CANCELED confirms that async\r
+       * cancelation succeeded.\r
+       */\r
+      assert(pthread_join(t[i], (void **) &result) == 0);\r
+\r
+      fail = (result != (int) PTHREAD_CANCELED);\r
+\r
+      if (fail)\r
+       {\r
+         fprintf(stderr, "Thread %d: started %d: count %d\n",\r
+                 i,\r
+                 threadbag[i].started,\r
+                 threadbag[i].count);\r
+       }\r
+      failed = (failed || fail);\r
+    }\r
+\r
+  assert(!failed);\r
+\r
+  /*\r
+   * Success.\r
+   */\r
+  return 0;\r
+}\r