@@ -15,7 +15,9 @@ import com.intellij.openapi.vfs.impl.VirtualFileManagerImpl
15
15
import com.intellij.openapi.vfs.impl.local.LocalFileSystemImpl
16
16
import com.intellij.platform.workspace.storage.url.VirtualFileUrl
17
17
import com.intellij.util.io.URLUtil
18
+ import com.jetbrains.rd.util.collections.SynchronizedMap
18
19
import java.io.*
20
+ import java.util.concurrent.ConcurrentLinkedQueue
19
21
import java.util.concurrent.LinkedBlockingQueue
20
22
import java.util.concurrent.TimeUnit
21
23
import java.util.concurrent.locks.ReentrantLock
@@ -57,9 +59,16 @@ class MyLogger(category: String): DefaultLogger(category) {
57
59
val myResourceLock = ReentrantLock ()
58
60
59
61
class WslSymlinksProvider (distro : String ) {
62
+ val LOGGER = Logger .getInstance(WslSymlinksProvider ::class .java)
60
63
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 ()
61
69
62
70
class AsyncValue {
71
+ public val id = this .hashCode().toString()
63
72
public var request: String? = null
64
73
internal var value: String? = null
65
74
internal val condition = myResourceLock.newCondition()
@@ -72,24 +81,18 @@ class WslSymlinksProvider(distro: String) {
72
81
}
73
82
elapsed + = 10
74
83
}
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
+ // }
78
87
return this .value
79
88
}
80
89
}
81
90
82
- private var process: Process
83
- private var processReader: BufferedReader
84
- private var processWriter: BufferedWriter
85
- private val queue: LinkedBlockingQueue <AsyncValue > = LinkedBlockingQueue ()
86
-
87
91
init {
88
92
val bash = {}.javaClass.getResource(" /files.sh" )?.readText()!!
89
93
val location = " \\\\ wsl.localhost\\ $distro \\ var\\ tmp\\ intellij-idea-wsl-symlinks.sh"
90
94
File (location).writeText(bash)
91
95
val builder = ProcessBuilder (" wsl.exe" , " -d" , distro, " -e" , " bash" , " //var/tmp/intellij-idea-wsl-symlinks.sh" )
92
- val outQueue: LinkedBlockingQueue <AsyncValue > = LinkedBlockingQueue ()
93
96
val process = builder.start()
94
97
this .process = process
95
98
@@ -102,28 +105,39 @@ class WslSymlinksProvider(distro: String) {
102
105
this .processWriter = writer;
103
106
104
107
process.onExit().whenComplete { t, u ->
108
+ LOGGER .error(" process did exit" , u)
105
109
this .process = builder.start()
106
110
this .processReader = BufferedReader (InputStreamReader (process.inputStream))
107
111
this .processWriter = BufferedWriter (OutputStreamWriter (process.outputStream));
108
112
}
109
113
110
114
thread {
111
115
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)
117
127
}
118
128
}
119
129
}
120
130
121
131
thread {
122
132
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
+ }
127
141
}
128
142
}
129
143
}
@@ -137,12 +151,17 @@ class WslSymlinksProvider(distro: String) {
137
151
try {
138
152
val wslPath = file.getWSLPath()
139
153
val a = AsyncValue ()
140
- a.request = " read-symlink;${wslPath} \n "
154
+ a.request = " ${a.id} ; read-symlink;${wslPath} \n "
141
155
this .queue.add(a)
156
+ while (a.getValue() == null ) {
157
+ if (! queue.contains(a)) {
158
+ this .queue.add(a)
159
+ }
160
+ }
142
161
val link = a.getValue()
143
162
file.cachedWSLCanonicalPath = file.path.split(" /" ).subList(0 , 4 ).joinToString(" /" ) + link
144
163
} catch (e: IOException ) {
145
- //
164
+ LOGGER .error( " failed to getWSLCanonicalPath " , e)
146
165
}
147
166
}
148
167
@@ -157,12 +176,17 @@ class WslSymlinksProvider(distro: String) {
157
176
try {
158
177
val path: String = file.path.replace(" ^//wsl\\ $/[^/]+" .toRegex(), " " ).replace(""" ^//wsl.localhost/[^/]+""" .toRegex(), " " )
159
178
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
+ }
162
185
val isSymLink = a.getValue()
163
186
file.isSymlink = isSymLink.equals(" true" )
164
187
return isSymLink.equals(" true" )
165
188
} catch (e: Exception ) {
189
+ LOGGER .error(" failed isWslSymlink" , e)
166
190
return false
167
191
}
168
192
}
0 commit comments