OSDN Git Service

* pinfo.cc (size_copied): New convenience macro.
authorcgf <cgf>
Mon, 12 Dec 2005 18:43:28 +0000 (18:43 +0000)
committercgf <cgf>
Mon, 12 Dec 2005 18:43:28 +0000 (18:43 +0000)
(winpids::add): Alias the element that we are working on for slightly better
clarity.  Honor the "make_copy" flag.
(winpids::release): Free and zero procinfo field if it was allocated via
malloc.
(winpids::~winpids): Free copied array.
* pinfo.h (class pinfo): Make winpids class a friend.
(winpids::make_copy): New field.
(winpids::copied): New array.
(winpids::reset): Reset npids after releasing pinfos or suffer a memory leak.
(winpids::winpids): Try harder to allocate all fields in the class.

winsup/cygwin/ChangeLog
winsup/cygwin/pinfo.cc
winsup/cygwin/pinfo.h

index 594744d..bb49e75 100644 (file)
@@ -1,3 +1,18 @@
+2005-12-12  Christopher Faylor  <cgf@timesys.com>
+
+       * pinfo.cc (size_copied): New convenience macro.
+       (winpids::add): Alias the element that we are working on for slightly
+       better clarity.  Honor the "make_copy" flag.
+       (winpids::release): Free and zero procinfo field if it was allocated
+       via malloc.
+       (winpids::~winpids): Free copied array.
+       * pinfo.h (class pinfo): Make winpids class a friend.
+       (winpids::make_copy): New field.
+       (winpids::copied): New array.
+       (winpids::reset): Reset npids after releasing pinfos or suffer a memory
+       leak.
+       (winpids::winpids): Try harder to allocate all fields in the class.
+
 2005-12-12  Corinna Vinschen  <corinna@vinschen.de>
 
        * autoload.cc (GetSystemTimes): Remove.
index fb3c9da..4e8f1a8 100644 (file)
@@ -1089,6 +1089,7 @@ cygwin_winpid_to_pid (int winpid)
 #define slop_pidlist 200
 #define size_pidlist(i) (sizeof (pidlist[0]) * ((i) + 1))
 #define size_pinfolist(i) (sizeof (pinfolist[0]) * ((i) + 1))
+#define size_copied(i) (sizeof (copied[0]) * ((i) + 1))
 
 inline void
 winpids::add (DWORD& nelem, bool winpid, DWORD pid)
@@ -1097,34 +1098,51 @@ winpids::add (DWORD& nelem, bool winpid, DWORD pid)
   if (nelem >= npidlist)
     {
       npidlist += slop_pidlist;
+      copied = (bool *) realloc (copied, size_copied (npidlist + 1));
       pidlist = (DWORD *) realloc (pidlist, size_pidlist (npidlist + 1));
       pinfolist = (pinfo *) realloc (pinfolist, size_pinfolist (npidlist + 1));
     }
 
-  pinfolist[nelem].init (cygpid, PID_NOREDIR | pinfo_access, NULL);
+  pinfo& p = pinfolist[nelem];
+
+  p.init (cygpid, PID_NOREDIR | pinfo_access, NULL);
   if (winpid)
     goto out;
 
-  if (!pinfolist[nelem])
+  if (!p)
     {
       if (!pinfo_access)
        return;
-      pinfolist[nelem].init (cygpid, PID_NOREDIR, NULL);
-      if (!pinfolist[nelem])
+      p.init (cygpid, PID_NOREDIR, NULL);
+      if (!p)
        return;
       }
 
   /* Scan list of previously recorded pids to make sure that this pid hasn't
      shown up before.  This can happen when a process execs. */
   for (unsigned i = 0; i < nelem; i++)
-    if (pinfolist[i]->pid == pinfolist[nelem]->pid)
+    if (pinfolist[i]->pid == p->pid)
       {
-       if ((_pinfo *) pinfolist[nelem] != (_pinfo *) myself)
-         pinfolist[nelem].release ();
+       if ((_pinfo *) p != (_pinfo *) myself)
+         p.release ();
        return;
       }
 
 out:
+  copied[nelem] = false;
+  if (make_copy)
+    {
+      _pinfo *pnew = (_pinfo *) malloc (sizeof (*p.procinfo));
+      if (pnew)
+       {
+         copied[nelem] = true;
+         *pnew = *p.procinfo;
+         if ((_pinfo *) p != (_pinfo *) myself)
+           p.release ();
+         p.procinfo = pnew;
+         p.destroy = false;
+       }
+    }
   pidlist[nelem++] = pid;
 }
 
@@ -1219,9 +1237,16 @@ winpids::enum_init (bool winpid)
 void
 winpids::release ()
 {
+  _pinfo *p;
   for (unsigned i = 0; i < npids; i++)
     if (pinfolist[i] && (_pinfo *) pinfolist[i] != (_pinfo *) myself)
-      pinfolist[i].release ();
+      if (!copied[i])
+       pinfolist[i].release ();
+      else if ((p = pinfolist[i].procinfo))
+       {
+         pinfolist[i].procinfo = NULL;
+         free (p);
+       }
 }
 
 winpids::~winpids ()
@@ -1229,6 +1254,7 @@ winpids::~winpids ()
   if (npidlist)
     {
       release ();
+      free (copied);
       free (pidlist);
       free (pinfolist);
     }
index d0c6349..6c701d5 100644 (file)
@@ -193,6 +193,7 @@ public:
   void set_acl ();
   void zap_cwd ();
   friend class _pinfo;
+  friend class winpids;
 };
 
 #define ISSTATE(p, f)  (!!((p)->process_state & f))
@@ -200,9 +201,11 @@ public:
 
 class winpids
 {
-  DWORD *pidlist;
+  bool make_copy;
   DWORD npidlist;
+  DWORD *pidlist;
   pinfo *pinfolist;
+  bool *copied;
   DWORD pinfo_access;          // access type for pinfo open
   DWORD (winpids::* enum_processes) (bool winpid);
   DWORD enum_init (bool winpid);
@@ -211,15 +214,16 @@ class winpids
   void add (DWORD& nelem, bool, DWORD pid);
 public:
   DWORD npids;
-  inline void reset () { npids = 0; release (); }
+  inline void reset () { release (); npids = 0;}
   void set (bool winpid);
-  winpids (): enum_processes (&winpids::enum_init) {}
-  winpids (int): pinfo_access (0), enum_processes (&winpids::enum_init)
-    { reset (); }
-  winpids (DWORD acc): pidlist (NULL), npidlist (0), pinfolist (NULL),
-                          enum_processes (&winpids::enum_init), npids (0)
+  winpids (): make_copy (true), enum_processes (&winpids::enum_init) {}
+  winpids (int): make_copy (false), npidlist (0), pidlist (NULL), pinfolist (NULL),
+                copied (NULL), pinfo_access (0), enum_processes (&winpids::enum_init),
+                npids (0) {}
+  winpids (DWORD acc): make_copy (false), npidlist (0), pidlist (NULL), pinfolist (NULL),
+                copied (NULL), pinfo_access (acc), enum_processes (&winpids::enum_init),
+                npids (0)
   {
-    pinfo_access = acc;
     set (0);
   }
   inline DWORD& winpid (int i) const {return pidlist[i];}