* path.cc (etc::dir_changed): Change `io' to a static NO_COPY

variable.  Explain why.  Add a muto to guard overwriting the changed_h
	handle by multiple concurrent threads.
	* path.h (class etc): Drop unused changed_h member.
This commit is contained in:
Corinna Vinschen 2012-07-31 19:36:16 +00:00
parent 217618d3d6
commit 68e41cfcf4
3 changed files with 40 additions and 22 deletions

View File

@ -1,3 +1,10 @@
2012-07-31 Corinna Vinschen <corinna@vinschen.de>
* path.cc (etc::dir_changed): Change `io' to a static NO_COPY
variable. Explain why. Add a muto to guard overwriting the changed_h
handle by multiple concurrent threads.
* path.h (class etc): Drop unused changed_h member.
2012-07-30 Christopher Faylor <me.cygwin2012@cgf.cx> 2012-07-30 Christopher Faylor <me.cygwin2012@cgf.cx>
* winlean.h: Define constant which will be needed eventually. Remove * winlean.h: Define constant which will be needed eventually. Remove

View File

@ -4311,46 +4311,58 @@ etc::test_file_change (int n)
bool bool
etc::dir_changed (int n) etc::dir_changed (int n)
{ {
static muto lock NO_COPY;
static HANDLE changed_h NO_COPY;
/* io MUST be static because NtNotifyChangeDirectoryFile works asynchronously.
It may write into io after the function has left, which may result in all
sorts of stack corruption. */
static IO_STATUS_BLOCK io NO_COPY;
if (!change_possible[n]) if (!change_possible[n])
{ {
static HANDLE changed_h NO_COPY;
NTSTATUS status; NTSTATUS status;
IO_STATUS_BLOCK io;
if (!changed_h) if (!changed_h)
{ {
OBJECT_ATTRIBUTES attr; OBJECT_ATTRIBUTES attr;
path_conv dir ("/etc"); lock.init ("etc_dir_changed_lock")->acquire ();
status = NtOpenFile (&changed_h, SYNCHRONIZE | FILE_LIST_DIRECTORY, if (!changed_h)
dir.get_object_attr (attr, sec_none_nih), &io,
FILE_SHARE_VALID_FLAGS, FILE_DIRECTORY_FILE);
if (!NT_SUCCESS (status))
{ {
path_conv dir ("/etc");
status = NtOpenFile (&changed_h,
SYNCHRONIZE | FILE_LIST_DIRECTORY,
dir.get_object_attr (attr, sec_none_nih),
&io, FILE_SHARE_VALID_FLAGS,
FILE_DIRECTORY_FILE);
if (!NT_SUCCESS (status))
{
#ifdef DEBUGGING #ifdef DEBUGGING
system_printf ("NtOpenFile (%S) failed, %p", system_printf ("NtOpenFile (%S) failed, %p",
dir.get_nt_native_path (), status); dir.get_nt_native_path (), status);
#endif #endif
changed_h = INVALID_HANDLE_VALUE; changed_h = INVALID_HANDLE_VALUE;
} }
else else
{ {
status = NtNotifyChangeDirectoryFile (changed_h, NULL, NULL, status = NtNotifyChangeDirectoryFile (changed_h, NULL, NULL,
NULL, &io, NULL, 0, NULL, &io, NULL, 0,
FILE_NOTIFY_CHANGE_LAST_WRITE FILE_NOTIFY_CHANGE_LAST_WRITE
| FILE_NOTIFY_CHANGE_FILE_NAME, | FILE_NOTIFY_CHANGE_FILE_NAME,
FALSE); FALSE);
if (!NT_SUCCESS (status)) if (!NT_SUCCESS (status))
{ {
#ifdef DEBUGGING #ifdef DEBUGGING
system_printf ("NtNotifyChangeDirectoryFile (1) failed, %p", system_printf ("NtNotifyChangeDirectoryFile (1) failed, "
status); "%p", status);
#endif #endif
NtClose (changed_h); NtClose (changed_h);
changed_h = INVALID_HANDLE_VALUE; changed_h = INVALID_HANDLE_VALUE;
}
} }
memset (change_possible, true, sizeof (change_possible));
} }
memset (change_possible, true, sizeof (change_possible)); lock.release ();
} }
if (changed_h == INVALID_HANDLE_VALUE) if (changed_h == INVALID_HANDLE_VALUE)

View File

@ -438,7 +438,6 @@ class etc
{ {
friend class dtable; friend class dtable;
static int curr_ix; static int curr_ix;
static HANDLE changed_h;
static bool change_possible[MAX_ETC_FILES + 1]; static bool change_possible[MAX_ETC_FILES + 1];
static OBJECT_ATTRIBUTES fn[MAX_ETC_FILES + 1]; static OBJECT_ATTRIBUTES fn[MAX_ETC_FILES + 1];
static LARGE_INTEGER last_modified[MAX_ETC_FILES + 1]; static LARGE_INTEGER last_modified[MAX_ETC_FILES + 1];