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:
authorMichael Haubenwallner <michael.haubenwallner@ssi-schaefer.com>2017-03-01 12:19:37 +0300
committerCorinna Vinschen <corinna@vinschen.de>2019-02-03 14:07:35 +0300
commit99fcc209dbb83c683a8e2c17e77bf427b70920c8 (patch)
treea902bff8cc7e05a34a56b82af79ed06814fa4994
parent98899c68a23fdc8f1e8f657272d870be4bbaea6e (diff)
forkables: simplify disabling via shm
* Rename cygwin_shared->prefer_forkable_hardlinks to forkable_hardlink_support, with values 0 for Unknown, 1 for Supported, -1 for Unsupported. Upon first dll loaded ever, dll_list::forkable_ntnamesize checks the /var/run/cygfork directory to both exist and reside on NTFS, setting cygwin_shared->forkable_hardlink_support accordingly. * Replace enum forkables_needs by bool forkables_created: Set to True by request_forkables after creating forkable hardlinks.
-rw-r--r--winsup/cygwin/dll_init.h21
-rw-r--r--winsup/cygwin/forkable.cc185
-rw-r--r--winsup/cygwin/include/cygwin/version.h2
-rw-r--r--winsup/cygwin/shared.cc1
-rw-r--r--winsup/cygwin/shared_info.h4
5 files changed, 65 insertions, 148 deletions
diff --git a/winsup/cygwin/dll_init.h b/winsup/cygwin/dll_init.h
index 45f71cb10..5c4cc0b29 100644
--- a/winsup/cygwin/dll_init.h
+++ b/winsup/cygwin/dll_init.h
@@ -87,17 +87,9 @@ struct dll
class dll_list
{
/* forkables */
- enum
- {
- forkables_unknown,
- forkables_impossible,
- forkables_disabled,
- forkables_needless,
- forkables_needed,
- forkables_created,
- }
- forkables_needs;
+ bool forkables_supported ();
DWORD forkables_dirx_size;
+ bool forkables_created;
PWCHAR forkables_dirx_ntname;
PWCHAR forkables_mutex_name;
HANDLE forkables_mutex;
@@ -160,10 +152,11 @@ public:
void cleanup_forkables ();
bool setup_forkables (bool with_forkables)
{
- if (forkables_needs == forkables_impossible)
- return true; /* short cut to not retry fork */
- /* Once used, always use forkables in current process chain. */
- if (forkables_needs != forkables_unknown)
+ if (!forkables_supported ())
+ return true; /* no need to retry fork */
+ if (forkables_created)
+ /* Once created, use forkables in current
+ process chain on first fork try already. */
with_forkables = true;
if (with_forkables)
request_forkables ();
diff --git a/winsup/cygwin/forkable.cc b/winsup/cygwin/forkable.cc
index c569b0f70..05b228517 100644
--- a/winsup/cygwin/forkable.cc
+++ b/winsup/cygwin/forkable.cc
@@ -501,17 +501,56 @@ dll::create_forkable ()
return false;
}
+bool
+dll_list::forkables_supported ()
+{
+ return cygwin_shared->forkable_hardlink_support >= 0;
+}
+
/* return the number of characters necessary to store one forkable name */
size_t
dll_list::forkable_ntnamesize (dll_type type, PCWCHAR fullntname, PCWCHAR modname)
{
/* per process, this is the first forkables-method ever called */
- if (forkables_needs == forkables_unknown &&
- !cygwin_shared->prefer_forkable_hardlinks)
- forkables_needs = forkables_impossible; /* short cut */
+ if (cygwin_shared->forkable_hardlink_support == 0) /* Unknown */
+ {
+ /* check existence of forkables dir */
+ PWCHAR pbuf = nt_max_path_buf ();
+ for (namepart const *part = forkable_nameparts; part->text; ++part)
+ {
+ if (part->textfunc)
+ pbuf += part->textfunc (pbuf, -1);
+ else
+ pbuf += __small_swprintf (pbuf, L"%W", part->text);
+ if (part->mutex_from_dir)
+ break; /* up to first mutex-naming dir */
+ }
+ pbuf = nt_max_path_buf ();
- if (forkables_needs == forkables_impossible)
- return 0;
+ UNICODE_STRING fn;
+ RtlInitUnicodeString (&fn, pbuf);
+
+ HANDLE dh = INVALID_HANDLE_VALUE;
+ fs_info fsi;
+ if (fsi.update (&fn, NULL) &&
+/* FIXME: !fsi.is_readonly () && */
+ fsi.is_ntfs ())
+ dh = ntopenfile (pbuf, NULL, FILE_DIRECTORY_FILE);
+ if (dh != INVALID_HANDLE_VALUE)
+ {
+ cygwin_shared->forkable_hardlink_support = 1; /* Yes */
+ NtClose (dh);
+ debug_printf ("enabled");
+ }
+ else
+ {
+ cygwin_shared->forkable_hardlink_support = -1; /* No */
+ debug_printf ("disabled, missing or not on NTFS %W", fn.Buffer);
+ }
+ }
+
+ if (!forkables_supported ())
+ return 0;
if (!forkables_dirx_size)
{
@@ -560,9 +599,6 @@ dll_list::forkable_ntnamesize (dll_type type, PCWCHAR fullntname, PCWCHAR modnam
void
dll_list::prepare_forkables_nomination ()
{
- if (!forkables_dirx_ntname)
- return;
-
dll *d = &dlls.start;
while ((d = d->next))
stat_real_file_once (d); /* uses nt_max_path_buf () */
@@ -627,106 +663,19 @@ dll_list::prepare_forkables_nomination ()
void
dll_list::update_forkables_needs ()
{
- dll *d;
-
- if (forkables_needs == forkables_unknown)
- {
- /* check if filesystem of forkables dir is NTFS */
- PWCHAR pbuf = nt_max_path_buf ();
- for (namepart const *part = forkable_nameparts; part->text; ++part)
- {
- if (part->mutex_from_dir)
- break; /* leading non-mutex-naming dirs, must exist anyway */
- if (part->textfunc)
- pbuf += part->textfunc (pbuf, -1);
- else
- pbuf += __small_swprintf (pbuf, L"%W", part->text);
- }
-
- UNICODE_STRING fn;
- RtlInitUnicodeString (&fn, nt_max_path_buf ());
-
- fs_info fsi;
- if (fsi.update (&fn, NULL) &&
-/* FIXME: !fsi.is_readonly () && */
- fsi.is_ntfs ())
- forkables_needs = forkables_disabled; /* check directory itself */
- else
- {
- debug_printf ("impossible, not on NTFS %W", fn.Buffer);
- forkables_needs = forkables_impossible;
- cygwin_shared->prefer_forkable_hardlinks = 0;
- }
- }
-
- if (forkables_needs == forkables_impossible)
- return; /* we have not created any hardlink, nothing to clean up */
-
- if (forkables_needs == forkables_disabled ||
- forkables_needs == forkables_needless ||
- forkables_needs == forkables_created)
- {
- /* (re-)check existence of forkables dir */
- PWCHAR pbuf = nt_max_path_buf ();
- for (namepart const *part = forkable_nameparts; part->text; ++part)
- {
- if (part->textfunc)
- pbuf += part->textfunc (pbuf, -1);
- else
- pbuf += __small_swprintf (pbuf, L"%W", part->text);
- if (part->mutex_from_dir)
- break; /* up to first mutex-naming dir */
- }
- pbuf = nt_max_path_buf ();
-
- HANDLE dh = ntopenfile (pbuf, NULL, FILE_DIRECTORY_FILE);
- if (dh != INVALID_HANDLE_VALUE)
- {
- NtClose (dh);
- if (forkables_needs == forkables_disabled)
- forkables_needs = forkables_needless;
- }
- else if (forkables_needs != forkables_disabled)
- {
- debug_printf ("disabled, disappearing %W", pbuf);
- close_mutex ();
- denominate_forkables ();
- forkables_needs = forkables_disabled;
- }
- else
- debug_printf ("disabled, missing %W", pbuf);
- }
-
- if (forkables_needs == forkables_disabled)
- return;
-
- if (forkables_needs == forkables_created)
+ if (forkables_created)
{
/* already have created hardlinks in this process, ... */
- forkables_needs = forkables_needless;
- d = &start;
+ dll *d = &start;
while ((d = d->next) != NULL)
if (d->forkable_ntname && !*d->forkable_ntname)
{
/* ... but another dll was loaded since last fork */
debug_printf ("needed, since last fork loaded %W", d->ntname);
- forkables_needs = forkables_needed;
+ forkables_created = false;
break;
}
}
-
- if (forkables_needs > forkables_needless)
- return; /* no need to check anything else */
-
- if (forkables_needs != forkables_needless)
- {
- /* paranoia */
- system_printf ("WARNING: invalid forkables_needs value %d",
- forkables_needs);
- return;
- }
-
- forkables_needs = forkables_needed;
}
/* Create the nominated forkable hardlinks and directories as necessary,
@@ -958,7 +907,7 @@ dll_list::close_mutex ()
void
dll_list::cleanup_forkables ()
{
- if (!forkables_dirx_ntname)
+ if (!forkables_supported ())
return;
bool locked = close_mutex ();
@@ -1034,58 +983,32 @@ dll_list::set_forkables_inheritance (bool inherit)
void
dll_list::request_forkables ()
{
- if (!forkables_dirx_ntname)
+ if (!forkables_supported ())
return;
- /* Even on forkables_impossible, keep the number of open handles
- stable across the fork, and close them when releasing only. */
prepare_forkables_nomination ();
update_forkables_needs ();
set_forkables_inheritance (true);
- if (forkables_needs == forkables_disabled)
- {
- /* we do not support (re-)enabling on the fly */
- forkables_needs = forkables_impossible;
- cygwin_shared->prefer_forkable_hardlinks = 0;
- }
-
- if (forkables_needs <= forkables_needless)
- return;
+ if (forkables_created)
+ return; /* nothing new to create */
dll *d = &start;
while ((d = d->next))
d->nominate_forkable (forkables_dirx_ntname);
- bool updated = update_forkables ();
-
- if (!updated)
- forkables_needs = forkables_needless;
- else
- forkables_needs = forkables_created;
+ if (update_forkables ())
+ forkables_created = true;
}
void
dll_list::release_forkables ()
{
- if (!forkables_dirx_ntname)
+ if (!forkables_supported ())
return;
set_forkables_inheritance (false);
-
- if (forkables_needs == forkables_impossible)
- {
- cleanup_forkables ();
-
- dll *d = &start;
- while ((d = d->next))
- d->forkable_ntname = NULL;
-
- cfree (forkables_dirx_ntname);
- forkables_dirx_ntname = NULL;
- forkables_mutex_name = NULL;
- }
}
diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h
index f7ed351d3..8926d49ae 100644
--- a/winsup/cygwin/include/cygwin/version.h
+++ b/winsup/cygwin/include/cygwin/version.h
@@ -518,7 +518,7 @@ details. */
regions. It is incremented when incompatible changes are made to the shared
memory region *or* to any named shared mutexes, semaphores, etc. */
-#define CYGWIN_VERSION_SHARED_DATA 6
+#define CYGWIN_VERSION_SHARED_DATA 5
/* An identifier used in the names used to create shared objects. The full
names include the CYGWIN_VERSION_SHARED_DATA version as well as this
diff --git a/winsup/cygwin/shared.cc b/winsup/cygwin/shared.cc
index e87f2f960..c939e0d0f 100644
--- a/winsup/cygwin/shared.cc
+++ b/winsup/cygwin/shared.cc
@@ -334,6 +334,7 @@ shared_info::initialize ()
NtAllocateLocallyUniqueId (&luid);/* Initialize pid_src to a low */
InterlockedExchange (&pid_src, /* random value to make start pid */
luid.LowPart % 2048);/* less predictably */
+ forkable_hardlink_support = 0; /* 0: Unknown, 1: Yes, -1: No */
/* Defer debug output printing the installation root and installation key
up to this point. Debug output except for system_printf requires
the global shared memory to exist. */
diff --git a/winsup/cygwin/shared_info.h b/winsup/cygwin/shared_info.h
index 8f0954f50..307306ce7 100644
--- a/winsup/cygwin/shared_info.h
+++ b/winsup/cygwin/shared_info.h
@@ -33,7 +33,7 @@ public:
/* Data accessible to all tasks */
-#define CURR_SHARED_MAGIC 0x3a6025edU
+#define CURR_SHARED_MAGIC 0xc590e67eU
#define USER_VERSION 1
@@ -51,7 +51,7 @@ class shared_info
mtinfo mt;
loadavginfo loadavg;
LONG pid_src;
- char prefer_forkable_hardlinks; /* single byte access always is atomic */
+ char forkable_hardlink_support; /* single byte access always is atomic */
void initialize ();
void init_obcaseinsensitive ();