Re: Understanding SWI's relationship with a C++ app's working directory.
Jan Wielemaker <[email protected]>
| Newsgroups | gmane.comp.ai.prolog.swi |
|---|---|
| Message-ID | <[email protected]> |
Hi Kaitain, Yes, the notion of the working directory is cached. SWI-Prolog is not a black box, so that would have been easy enough to find :-) There are two (undocumented) calls to get Prolog's notion of the working directory (PL_cwd()) and one to tell that you changed it, so the cached version is no longer reliable (PL_changed_cwd()). At some point in the past, Unix functions to get the working directory were really slow and old SWI-Prolog changed working directory when loading files. As the WD is a process wide setting, this stopped working with the introduction of threads. I don't know what the current situation is. It seems both Unix and Windows still use a per-process notion of the working directory. Windows specifically states you should not play with that after program startup [1] in a multithreaded application. I think they are right (although the comment suggests you actually may get corrupted path names if there is a concurrent modification, while one would assume one gets at worst only the old incorrect value). If nobody messes with it anyway, caching it cannot be a bad idea. On the other hand, OSes and C runtime libs may have evolved enough to make sure getcwd() is fast and/or cached at the library level. If that is the case, we can use the C runtime versions and forget about our cache. I think there are two options: remove the caching or document it. Does anyone have some overview about the performance of getcwd() or equivalent in todays OSes? Cheers --- Jan P.s. Note that SWI-Prolog's source administration is based on absolute paths. [1] http://msdn.microsoft.com/en-us/library/windows/desktop/aa364934%28v=vs.85%29.aspx On 03/04/2014 08:10 AM, Kaitain Jones wrote: > Spent several hours today trying to wrap my head around how > SWI-Prolog sets and caches the working directory using > working_directory/2, and how this interacts with a C++ app's working > directory as set using _chdir() (on PC using MSVC). I was having > problems with the consultation of files suddenly failing at a certain > point during program execution. What I found seems a bit quirky and I > wonder if this is all by design or whether something might have been > overlooked. > > My first thought wrt. the failed consult operation was that the > working directory might be getting changed by something, so that > subsequent consults were pointing at the wrong target directory. But > calling > > working_directory( X, X ) > > ...returned the current working directory as being exactly the one I > wanted. Yet I ascertained that it was indeed a call to _chdir > elsewhere in the C app that was almost certainly causing subsequent > failure. > > What I tried next was a call to reimpose my intended working > directory using working_directory/2, but this didn't help. However, > removing the _chdir call in the C code eliminated the problem, as did > making a subsequent _chdir call to a hard-coded absolute path that > was the one the SWI stuff needed to be pointed at. So SWI definitely > seemed to be using the global app-level WD as set by _chdir(). > > I then wondered whether the SWI system might be using its own > internal cached value, and deciding that if the user was asking to > set the working directory to the same directory used last time > working_directory/2 was used, it should do nothing at all. So if I > first used working_directory to change to a different (arbitrary) > directory then back to the original (desired) one, would it work? > Answer: yes. So I'm currently using a bizarre hack whereby every time > I want to consult a file, I first: > > a) Use working_directory to set the WD as some other undesired > directory b) Use working_directory AGAIN to switch to the actual > desired directory c) Consult the file > > This works, reliably. But it raises several questions, not least: > > 1. Is it an oversight that SWI ignores a call to set the > working_directory to the same value last used, given that the working > directory can be set by code outside of SWI's jurisdiction? 2. Wait a > minute, why is SWI using the app's globally-set working directory > anyway? Shouldn't it have its own internal concept of a working > directory and not care about the app-level one that is set when > _chdir() is called? 3. If the SWI working directory and the app-level > WD are one and the same, why does SWI seem to have its own internal > cached value of what the WD is that gets used when > working_directory/2 is called (it will claim to be using directory D > even when D is NOT the actual WD, and will ignore attempts to set the > WD to D if it think it already is D) yet it will use the app's global > WD whenever a consult operation is called rather than its internal > cached WD value? > > Of course, I was just using the system as a black box today and its > behaviour *suggested* the existence of such a cached value, but I may > be misunderstanding what is actually going on. > > KJ -------------- next part -------------- HTML attachment scrubbed > and removed _______________________________________________ > SWI-Prolog mailing list [email protected] > https://lists.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog >