4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-02-19 07:22:14 +08:00

* 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.
This commit is contained in:
Christopher Faylor 2005-12-12 18:43:31 +00:00
parent 9941f8525d
commit 363934dc9b
3 changed files with 61 additions and 16 deletions

View 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> 2005-12-12 Corinna Vinschen <corinna@vinschen.de>
* autoload.cc (GetSystemTimes): Remove. * autoload.cc (GetSystemTimes): Remove.

View File

@ -1089,6 +1089,7 @@ cygwin_winpid_to_pid (int winpid)
#define slop_pidlist 200 #define slop_pidlist 200
#define size_pidlist(i) (sizeof (pidlist[0]) * ((i) + 1)) #define size_pidlist(i) (sizeof (pidlist[0]) * ((i) + 1))
#define size_pinfolist(i) (sizeof (pinfolist[0]) * ((i) + 1)) #define size_pinfolist(i) (sizeof (pinfolist[0]) * ((i) + 1))
#define size_copied(i) (sizeof (copied[0]) * ((i) + 1))
inline void inline void
winpids::add (DWORD& nelem, bool winpid, DWORD pid) winpids::add (DWORD& nelem, bool winpid, DWORD pid)
@ -1097,34 +1098,51 @@ winpids::add (DWORD& nelem, bool winpid, DWORD pid)
if (nelem >= npidlist) if (nelem >= npidlist)
{ {
npidlist += slop_pidlist; npidlist += slop_pidlist;
copied = (bool *) realloc (copied, size_copied (npidlist + 1));
pidlist = (DWORD *) realloc (pidlist, size_pidlist (npidlist + 1)); pidlist = (DWORD *) realloc (pidlist, size_pidlist (npidlist + 1));
pinfolist = (pinfo *) realloc (pinfolist, size_pinfolist (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) if (winpid)
goto out; goto out;
if (!pinfolist[nelem]) if (!p)
{ {
if (!pinfo_access) if (!pinfo_access)
return; return;
pinfolist[nelem].init (cygpid, PID_NOREDIR, NULL); p.init (cygpid, PID_NOREDIR, NULL);
if (!pinfolist[nelem]) if (!p)
return; return;
} }
/* Scan list of previously recorded pids to make sure that this pid hasn't /* Scan list of previously recorded pids to make sure that this pid hasn't
shown up before. This can happen when a process execs. */ shown up before. This can happen when a process execs. */
for (unsigned i = 0; i < nelem; i++) 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) if ((_pinfo *) p != (_pinfo *) myself)
pinfolist[nelem].release (); p.release ();
return; return;
} }
out: 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; pidlist[nelem++] = pid;
} }
@ -1219,9 +1237,16 @@ winpids::enum_init (bool winpid)
void void
winpids::release () winpids::release ()
{ {
_pinfo *p;
for (unsigned i = 0; i < npids; i++) for (unsigned i = 0; i < npids; i++)
if (pinfolist[i] && (_pinfo *) pinfolist[i] != (_pinfo *) myself) 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 () winpids::~winpids ()
@ -1229,6 +1254,7 @@ winpids::~winpids ()
if (npidlist) if (npidlist)
{ {
release (); release ();
free (copied);
free (pidlist); free (pidlist);
free (pinfolist); free (pinfolist);
} }

View File

@ -193,6 +193,7 @@ public:
void set_acl (); void set_acl ();
void zap_cwd (); void zap_cwd ();
friend class _pinfo; friend class _pinfo;
friend class winpids;
}; };
#define ISSTATE(p, f) (!!((p)->process_state & f)) #define ISSTATE(p, f) (!!((p)->process_state & f))
@ -200,9 +201,11 @@ public:
class winpids class winpids
{ {
DWORD *pidlist; bool make_copy;
DWORD npidlist; DWORD npidlist;
DWORD *pidlist;
pinfo *pinfolist; pinfo *pinfolist;
bool *copied;
DWORD pinfo_access; // access type for pinfo open DWORD pinfo_access; // access type for pinfo open
DWORD (winpids::* enum_processes) (bool winpid); DWORD (winpids::* enum_processes) (bool winpid);
DWORD enum_init (bool winpid); DWORD enum_init (bool winpid);
@ -211,15 +214,16 @@ class winpids
void add (DWORD& nelem, bool, DWORD pid); void add (DWORD& nelem, bool, DWORD pid);
public: public:
DWORD npids; DWORD npids;
inline void reset () { npids = 0; release (); } inline void reset () { release (); npids = 0;}
void set (bool winpid); void set (bool winpid);
winpids (): enum_processes (&winpids::enum_init) {} winpids (): make_copy (true), enum_processes (&winpids::enum_init) {}
winpids (int): pinfo_access (0), enum_processes (&winpids::enum_init) winpids (int): make_copy (false), npidlist (0), pidlist (NULL), pinfolist (NULL),
{ reset (); } copied (NULL), pinfo_access (0), enum_processes (&winpids::enum_init),
winpids (DWORD acc): pidlist (NULL), npidlist (0), pinfolist (NULL), npids (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); set (0);
} }
inline DWORD& winpid (int i) const {return pidlist[i];} inline DWORD& winpid (int i) const {return pidlist[i];}