Skip to content

Commit 3fee567

Browse files
committed
fix lock
1 parent 023fdcf commit 3fee567

File tree

5 files changed

+55
-30
lines changed

5 files changed

+55
-30
lines changed

.idea/vcs.xml

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build.gradle.kts

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ plugins {
1313

1414

1515
group = "com.wsl.symlinks"
16-
version = "2024.1.0"
16+
version = "2024.1.1"
1717

1818
// Configure project's dependencies
1919
repositories {

src/main/kotlin/com/wsl/symlinks/vfs/WslVirtualFileSystem.kt

+46-22
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ import com.intellij.openapi.vfs.impl.VirtualFileManagerImpl
1515
import com.intellij.openapi.vfs.impl.local.LocalFileSystemImpl
1616
import com.intellij.platform.workspace.storage.url.VirtualFileUrl
1717
import com.intellij.util.io.URLUtil
18+
import com.jetbrains.rd.util.collections.SynchronizedMap
1819
import java.io.*
20+
import java.util.concurrent.ConcurrentLinkedQueue
1921
import java.util.concurrent.LinkedBlockingQueue
2022
import java.util.concurrent.TimeUnit
2123
import java.util.concurrent.locks.ReentrantLock
@@ -57,9 +59,16 @@ class MyLogger(category: String): DefaultLogger(category) {
5759
val myResourceLock = ReentrantLock()
5860

5961
class WslSymlinksProvider(distro: String) {
62+
val LOGGER = Logger.getInstance(WslSymlinksProvider::class.java)
6063

64+
private var process: Process
65+
private var processReader: BufferedReader
66+
private var processWriter: BufferedWriter
67+
private val queue: LinkedBlockingQueue<AsyncValue> = LinkedBlockingQueue()
68+
private val mapped: SynchronizedMap<String, AsyncValue> = SynchronizedMap()
6169

6270
class AsyncValue {
71+
public val id = this.hashCode().toString()
6372
public var request: String? = null
6473
internal var value: String? = null
6574
internal val condition = myResourceLock.newCondition()
@@ -72,24 +81,18 @@ class WslSymlinksProvider(distro: String) {
7281
}
7382
elapsed += 10
7483
}
75-
if (this.value == null) {
76-
throw Error("failed to obtain file info for $request")
77-
}
84+
// if (this.value == null) {
85+
// throw Error("failed to obtain file info for $request")
86+
// }
7887
return this.value
7988
}
8089
}
8190

82-
private var process: Process
83-
private var processReader: BufferedReader
84-
private var processWriter: BufferedWriter
85-
private val queue: LinkedBlockingQueue<AsyncValue> = LinkedBlockingQueue()
86-
8791
init {
8892
val bash = {}.javaClass.getResource("/files.sh")?.readText()!!
8993
val location = "\\\\wsl.localhost\\$distro\\var\\tmp\\intellij-idea-wsl-symlinks.sh"
9094
File(location).writeText(bash)
9195
val builder = ProcessBuilder("wsl.exe", "-d", distro, "-e", "bash", "//var/tmp/intellij-idea-wsl-symlinks.sh")
92-
val outQueue: LinkedBlockingQueue<AsyncValue> = LinkedBlockingQueue()
9396
val process = builder.start()
9497
this.process = process
9598

@@ -102,28 +105,39 @@ class WslSymlinksProvider(distro: String) {
102105
this.processWriter = writer;
103106

104107
process.onExit().whenComplete { t, u ->
108+
LOGGER.error("process did exit", u)
105109
this.process = builder.start()
106110
this.processReader = BufferedReader(InputStreamReader(process.inputStream))
107111
this.processWriter = BufferedWriter(OutputStreamWriter(process.outputStream));
108112
}
109113

110114
thread {
111115
while (true) {
112-
val a = outQueue.take()
113-
val line = this.processReader.readLine()
114-
a.value = line
115-
myResourceLock.withLock {
116-
a.condition.signalAll()
116+
try {
117+
val line = this.processReader.readLine()
118+
val (id, answer) = line.split(";")
119+
val a = mapped[id]!!
120+
a.value = answer
121+
myResourceLock.withLock {
122+
a.condition.signalAll()
123+
}
124+
mapped.remove(id)
125+
} catch (e: Exception) {
126+
LOGGER.error("failed to write", e)
117127
}
118128
}
119129
}
120130

121131
thread {
122132
while (true) {
123-
val a = this.queue.take()
124-
outQueue.add(a)
125-
this.processWriter.write(a.request!!)
126-
this.processWriter.flush()
133+
try {
134+
val a = this.queue.take()
135+
mapped[a.id] = a
136+
this.processWriter.write(a.request!!)
137+
this.processWriter.flush()
138+
} catch (e: Exception) {
139+
LOGGER.error("failed to write", e)
140+
}
127141
}
128142
}
129143
}
@@ -137,12 +151,17 @@ class WslSymlinksProvider(distro: String) {
137151
try {
138152
val wslPath = file.getWSLPath()
139153
val a = AsyncValue()
140-
a.request = "read-symlink;${wslPath}\n"
154+
a.request = "${a.id};read-symlink;${wslPath}\n"
141155
this.queue.add(a)
156+
while (a.getValue() == null) {
157+
if (!queue.contains(a)) {
158+
this.queue.add(a)
159+
}
160+
}
142161
val link = a.getValue()
143162
file.cachedWSLCanonicalPath = file.path.split("/").subList(0, 4).joinToString("/") + link
144163
} catch (e: IOException) {
145-
//
164+
LOGGER.error("failed to getWSLCanonicalPath", e)
146165
}
147166
}
148167

@@ -157,12 +176,17 @@ class WslSymlinksProvider(distro: String) {
157176
try {
158177
val path: String = file.path.replace("^//wsl\\$/[^/]+".toRegex(), "").replace("""^//wsl.localhost/[^/]+""".toRegex(), "")
159178
val a = AsyncValue()
160-
a.request = "is-symlink;${path}\n"
161-
this.queue.add(a)
179+
a.request = "${a.id};is-symlink;${path}\n"
180+
while (a.getValue() == null) {
181+
if (!queue.contains(a)) {
182+
this.queue.add(a)
183+
}
184+
}
162185
val isSymLink = a.getValue()
163186
file.isSymlink = isSymLink.equals("true")
164187
return isSymLink.equals("true")
165188
} catch (e: Exception) {
189+
LOGGER.error("failed isWslSymlink", e)
166190
return false
167191
}
168192
}

src/main/resources/META-INF/plugin.xml

+1-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99
]]></description>
1010

1111
<change-notes><![CDATA[
12-
13-
see <a href="https://github.com/patricklx/intellij-wsl-symlinks/blob/main/CHANGELOG.md">https://github.com/patricklx/intellij-wsl-symlinks/</a> for more
12+
CHANGELOG_PLACEHOLDER
1413
]]>
1514
</change-notes>
1615

src/main/resources/files.sh

+6-4
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@ while IFS='$\n' read line
22
do
33
IFS=';'
44
read -ra command <<< "$line"
5-
type=${command[0]}
6-
value=${command[1]}
5+
id=${command[0]}
6+
type=${command[1]}
7+
value=${command[2]}
78
if [ "$type" == "is-symlink" ]; then
8-
(test -L "$value") && echo "true" || echo "false"
9+
(test -L "$value") && echo "$id;true" || echo "$id;false"
910
fi
1011
if [ "$type" == "read-symlink" ]; then
11-
readlink -f "$value"
12+
link=$(readlink -f "$value")
13+
echo "$id;$link"
1214
fi
1315
done

0 commit comments

Comments
 (0)