public inbox for cygwin-cvs@sourceware.org
help / color / mirror / Atom feed
From: Corinna Vinschen <corinna@sourceware.org>
To: cygwin-cvs@sourceware.org
Subject: [newlib-cygwin] Cygwin: get/setrlimit: move RLIMIT_AS handling into static functions
Date: Tue, 30 Nov 2021 11:56:14 +0000 (GMT)	[thread overview]
Message-ID: <20211130115614.43DB0385783E@sourceware.org> (raw)

https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=3edea7cd55d178164a649d9eea252c807ed2c038

commit 3edea7cd55d178164a649d9eea252c807ed2c038
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Tue Nov 30 12:54:03 2021 +0100

    Cygwin: get/setrlimit: move RLIMIT_AS handling into static functions
    
    To keep getrlimit/setrlimit clean, move the RLIMIT_AS code into
    local static functions __set_rlimit_as and __get_rlimit_as.
    
    Also, make adding process to the job the last step, to be able to
    close and release the job resources if anything failed.  Add matching
    comment.
    
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 winsup/cygwin/resource.cc | 157 +++++++++++++++++++++++++---------------------
 1 file changed, 84 insertions(+), 73 deletions(-)

diff --git a/winsup/cygwin/resource.cc b/winsup/cygwin/resource.cc
index c4c79ca6f..21e85bd18 100644
--- a/winsup/cygwin/resource.cc
+++ b/winsup/cygwin/resource.cc
@@ -174,6 +174,87 @@ job_shared_name (PWCHAR buf, LONG num)
   return buf;
 }
 
+static void
+__get_rlimit_as (struct rlimit *rlp)
+{
+  UNICODE_STRING uname;
+  WCHAR jobname[32];
+  OBJECT_ATTRIBUTES attr;
+  HANDLE job = NULL;
+  NTSTATUS status;
+  JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobinfo;
+
+  if (cygheap->rlim_as_id)
+    {
+      RtlInitUnicodeString (&uname,
+			    job_shared_name (jobname,
+					     cygheap->rlim_as_id));
+      InitializeObjectAttributes (&attr, &uname, 0,
+				  get_session_parent_dir (), NULL);
+      /* May fail, just check NULL job in that case. */
+      NtOpenJobObject (&job, JOB_OBJECT_QUERY, &attr);
+    }
+  status = NtQueryInformationJobObject (job,
+			      JobObjectExtendedLimitInformation,
+			      &jobinfo, sizeof jobinfo, NULL);
+  if (NT_SUCCESS (status)
+      && (jobinfo.BasicLimitInformation.LimitFlags
+	  & JOB_OBJECT_LIMIT_PROCESS_MEMORY))
+    rlp->rlim_cur = rlp->rlim_max = jobinfo.ProcessMemoryLimit;
+  if (job)
+    NtClose (job);
+}
+
+static int
+__set_rlimit_as (unsigned long new_as_limit)
+{
+  LONG new_as_id = 0;
+  UNICODE_STRING uname;
+  WCHAR jobname[32];
+  OBJECT_ATTRIBUTES attr;
+  NTSTATUS status = STATUS_SUCCESS;
+  HANDLE job = NULL;
+  JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobinfo = { 0 };
+
+  /* If we already have a limit, we must not change it because that
+     would potentially influence already running child processes.
+     Just try to create another, nested job.  On systems prior to
+     Windows 8 / Server 2012 this will fail, but that's ok. */
+  while (new_as_id == 0)
+    new_as_id = InterlockedIncrement (&job_serial_number);
+  RtlInitUnicodeString (&uname,
+			job_shared_name (jobname, new_as_id));
+  InitializeObjectAttributes (&attr, &uname, 0,
+			      get_session_parent_dir (), NULL);
+  status = NtCreateJobObject (&job, JOB_OBJECT_ALL_ACCESS, &attr);
+  if (!NT_SUCCESS (status))
+    {
+      __seterrno_from_nt_status (status);
+      return -1;
+    }
+  jobinfo.BasicLimitInformation.LimitFlags
+    = JOB_OBJECT_LIMIT_PROCESS_MEMORY;
+  /* Per Linux man page, round down to system pagesize. */
+  jobinfo.ProcessMemoryLimit
+    = rounddown (new_as_limit, wincap.allocation_granularity ());
+  status = NtSetInformationJobObject (job,
+				JobObjectExtendedLimitInformation,
+				&jobinfo, sizeof jobinfo);
+  /* If creating the job and setting up the job limits succeeded,
+     try to add the process to the job.  This must be the last step,
+     otherwise we couldn't remove the job if anything failed. */
+  if (NT_SUCCESS (status))
+    status = NtAssignProcessToJobObject (job, NtCurrentProcess ());
+  NtClose (job);
+  if (!NT_SUCCESS (status))
+    {
+      __seterrno_from_nt_status (status);
+      return -1;
+    }
+  cygheap->rlim_as_id = new_as_id;
+  return 0;
+}
+
 extern "C" int
 getrlimit (int resource, struct rlimit *rlp)
 {
@@ -189,34 +270,7 @@ getrlimit (int resource, struct rlimit *rlp)
 	case RLIMIT_DATA:
 	  break;
 	case RLIMIT_AS:
-	  {
-	    UNICODE_STRING uname;
-	    WCHAR jobname[32];
-	    OBJECT_ATTRIBUTES attr;
-	    HANDLE job = NULL;
-	    NTSTATUS status;
-	    JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobinfo;
-
-	    if (cygheap->rlim_as_id)
-	      {
-		RtlInitUnicodeString (&uname,
-				      job_shared_name (jobname,
-						       cygheap->rlim_as_id));
-		InitializeObjectAttributes (&attr, &uname, 0,
-					    get_session_parent_dir (), NULL);
-		/* May fail, just check NULL job in that case. */
-		NtOpenJobObject (&job, JOB_OBJECT_QUERY, &attr);
-	      }
-	    status = NtQueryInformationJobObject (job,
-					JobObjectExtendedLimitInformation,
-					&jobinfo, sizeof jobinfo, NULL);
-	    if (!NT_SUCCESS (status))
-	      break;
-	    if (jobinfo.BasicLimitInformation.LimitFlags & JOB_OBJECT_LIMIT_PROCESS_MEMORY)
-	      rlp->rlim_cur = rlp->rlim_max = jobinfo.ProcessMemoryLimit;
-	    if (job)
-	      NtClose (job);
-	  }
+	  __get_rlimit_as (rlp);
 	  break;
 	case RLIMIT_STACK:
 	  __get_rlimit_stack (rlp);
@@ -270,51 +324,8 @@ setrlimit (int resource, const struct rlimit *rlp)
       switch (resource)
 	{
 	case RLIMIT_AS:
-	  {
-	    LONG new_as_id = 0;
-	    UNICODE_STRING uname;
-	    WCHAR jobname[32];
-	    OBJECT_ATTRIBUTES attr;
-	    NTSTATUS status = STATUS_SUCCESS;
-	    HANDLE job = NULL;
-	    JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobinfo = { 0 };
-
-	    /* If we already have a limit, we must not change it because that
-	       would potentially influence already running child processes.
-	       Just try to create another, nested job.  On systems prior to
-	       Windows 8 / Server 2012 this will fail, but that's ok. */
-	    while (new_as_id == 0)
-	      new_as_id = InterlockedIncrement (&job_serial_number);
-	    RtlInitUnicodeString (&uname,
-				  job_shared_name (jobname, new_as_id));
-	    InitializeObjectAttributes (&attr, &uname, 0,
-					get_session_parent_dir (), NULL);
-	    status = NtCreateJobObject (&job, JOB_OBJECT_ALL_ACCESS, &attr);
-	    if (!NT_SUCCESS (status))
-	      {
-		__seterrno_from_nt_status (status);
-		__leave;
-	      }
-	    status = NtAssignProcessToJobObject (job, NtCurrentProcess ());
-	    if (NT_SUCCESS (status))
-	      {
-		jobinfo.BasicLimitInformation.LimitFlags
-		  = JOB_OBJECT_LIMIT_PROCESS_MEMORY;
-		/* Per Linux man page, round down to system pagesize. */
-		jobinfo.ProcessMemoryLimit
-		  = rounddown (rlp->rlim_cur, wincap.allocation_granularity ());
-		status = NtSetInformationJobObject (job,
-					      JobObjectExtendedLimitInformation,
-					      &jobinfo, sizeof jobinfo);
-	      }
-	    NtClose (job);
-	    if (!NT_SUCCESS (status))
-	      {
-		__seterrno_from_nt_status (status);
-		__leave;
-	      }
-	    cygheap->rlim_as_id = new_as_id;
-	  }
+	  if (rlp->rlim_cur != RLIM_INFINITY)
+	    return __set_rlimit_as (rlp->rlim_cur);
 	  break;
 	case RLIMIT_CORE:
 	  cygheap->rlim_core = rlp->rlim_cur;


                 reply	other threads:[~2021-11-30 11:56 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211130115614.43DB0385783E@sourceware.org \
    --to=corinna@sourceware.org \
    --cc=cygwin-cvs@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).