Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2005-12-12 21:43:31 +0300
committerChristopher Faylor <me@cgf.cx>2005-12-12 21:43:31 +0300
commit363934dc9b9327460fefc113a3797e7e51ea2c18 (patch)
tree240bbce2428abbce4c633f33a879b4a5baba1994
parent9941f8525d6a586843662352f28409efa18942c8 (diff)
* 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.
-rw-r--r--winsup/cygwin/ChangeLog15
-rw-r--r--winsup/cygwin/pinfo.cc42
-rw-r--r--winsup/cygwin/pinfo.h20
3 files changed, 61 insertions, 16 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 594744d40..bb49e7578 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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.
diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc
index fb3c9da14..4e8f1a899 100644
--- a/winsup/cygwin/pinfo.cc
+++ b/winsup/cygwin/pinfo.cc
@@ -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);
}
diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h
index d0c634909..6c701d5a8 100644
--- a/winsup/cygwin/pinfo.h
+++ b/winsup/cygwin/pinfo.h
@@ -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];}