Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
com.ccwangluo.accelerator
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
sheteng
com.ccwangluo.accelerator
Commits
c19eb4e9
Commit
c19eb4e9
authored
Mar 07, 2016
by
ayanamist
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Convert GuardedProcess to Scala
parent
cad6d7b6
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
147 additions
and
0 deletions
+147
-0
src/main/java/com/github/shadowsocks/GuardedProcess.scala
src/main/java/com/github/shadowsocks/GuardedProcess.scala
+147
-0
No files found.
src/main/java/com/github/shadowsocks/GuardedProcess.
jav
a
→
src/main/java/com/github/shadowsocks/GuardedProcess.
scal
a
View file @
c19eb4e9
...
...
@@ -37,109 +37,111 @@
*
*/
package
com.github.shadowsocks
;
package
com.github.shadowsocks
import
android.util.Log
;
import
android.util.Log
import
java.io.IOException
import
java.io.InputStream
import
java.io.OutputStream
import
java.util.concurrent.CountDownLatch
import
java.util.concurrent.atomic.AtomicReference
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.lang.System
;
import
java.util.Arrays
;
import
java.util.List
;
import
java.util.concurrent.CountDownLatch
;
import
java.util.concurrent.atomic.AtomicReference
;
import
collection.JavaConversions._
public
class
GuardedProcess
extends
Process
{
private
static
final
String
TAG
=
GuardedProcess
.
class
.
getSimpleName
();
private
final
Thread
guardThread
;
private
volatile
boolean
isDestroyed
=
false
;
private
volatile
Process
process
=
null
;
object
GuardedProcess
{
private
val
TAG
:
String
=
classOf
[
GuardedProcess
].
getSimpleName
public
GuardedProcess
(
String
...
cmd
)
throws
InterruptedException
,
IOException
{
this
(
Arrays
.
asList
(
cmd
));
@throws
(
classOf
[
IOException
])
private
def
startProcess
(
cmd
:
Seq
[
String
])
:
Process
=
{
new
ProcessBuilder
(
cmd
).
redirectErrorStream
(
true
).
start
}
}
class
GuardedProcess
extends
Process
{
private
var
guardThread
:
Thread
=
null
@volatile
private
var
isDestroyed
:
Boolean
=
false
@volatile
private
var
process
:
Process
=
null
public
GuardedProcess
(
final
List
<
String
>
cmd
)
throws
InterruptedException
,
IOException
{
this
(
cmd
,
null
);
@throws
(
classOf
[
InterruptedException
])
@throws
(
classOf
[
IOException
])
def
this
(
cmd
:
Seq
[
String
],
onRestartCallback
:
Runnable
=
null
)
{
this
()
initThread
(
cmd
,
onRestartCallback
)
}
public
GuardedProcess
(
final
List
<
String
>
cmd
,
final
Runnable
onRestartCallback
)
throws
InterruptedException
,
IOException
{
final
CountDownLatch
countDownLatch
=
new
CountDownLatch
(
1
);
final
AtomicReference
<
IOException
>
atomicIoException
=
new
AtomicReference
<
IOException
>(
null
);
def
initThread
(
cmd
:
Seq
[
String
],
onRestartCallback
:
Runnable
)
:
Unit
=
{
val
atomicIoException
:
AtomicReference
[
IOException
]
=
new
AtomicReference
[
IOException
](
null
)
val
countDownLatch
:
CountDownLatch
=
new
CountDownLatch
(
1
)
guardThread
=
new
Thread
(
new
Runnable
()
{
@Override
public
void
run
()
{
override
def
run
()
:
Unit
=
{
try
{
while
(!
isDestroyed
)
{
Log
.
i
(
TAG
,
"start process: "
+
cmd
);
long
startTime
=
System
.
currentTimeMillis
();
process
=
startProcess
(
cmd
);
if
(
onRestartCallback
!=
null
&&
countDownLatch
.
getCount
()
<=
0
)
{
onRestartCallback
.
run
();
}
countDownLatch
.
countDown
();
process
.
waitFor
();
if
(
System
.
currentTimeMillis
()
-
startTime
<
1000
)
{
Log
.
w
(
TAG
,
"process exit too fast, stop guard: "
+
cmd
);
break
;
}
}
}
catch
(
InterruptedException
ignored
)
{
Log
.
i
(
TAG
,
"thread interrupt, destroy process: "
+
cmd
);
process
.
destroy
();
}
catch
(
IOException
e
)
{
atomicIoException
.
compareAndSet
(
null
,
e
);
Log
.
i
(
GuardedProcess
.
TAG
,
"start process: "
+
cmd
)
val
startTime
:
Long
=
java
.
lang
.
System
.
currentTimeMillis
process
=
GuardedProcess
.
startProcess
(
cmd
)
if
(
onRestartCallback
!=
null
&&
countDownLatch
.
getCount
<=
0
)
{
onRestartCallback
.
run
()
}
countDownLatch
.
countDown
()
process
.
waitFor
if
(
java
.
lang
.
System
.
currentTimeMillis
-
startTime
<
1000
)
{
Log
.
w
(
GuardedProcess
.
TAG
,
"process exit too fast, stop guard: "
+
cmd
)
return
}
}
}
catch
{
case
ignored
:
InterruptedException
=>
Log
.
i
(
GuardedProcess
.
TAG
,
"thread interrupt, destroy process: "
+
cmd
)
process
.
destroy
()
case
e
:
IOException
=>
atomicIoException
.
compareAndSet
(
null
,
e
)
}
finally
{
countDownLatch
.
countDown
();
countDownLatch
.
countDown
()
}
}
},
"GuardThread-"
+
cmd
);
guardThread
.
start
();
countDownLatch
.
await
();
IOException
ioException
=
atomicIoException
.
get
();
},
"GuardThread-"
+
cmd
)
guardThread
.
start
()
countDownLatch
.
await
()
val
ioException
:
IOException
=
atomicIoException
.
get
if
(
ioException
!=
null
)
{
throw
ioException
;
throw
ioException
}
}
private
static
Process
startProcess
(
List
<
String
>
cmd
)
throws
IOException
{
return
new
ProcessBuilder
(
cmd
).
redirectErrorStream
(
true
).
start
();
}
public
void
destroy
()
{
isDestroyed
=
true
;
guardThread
.
interrupt
();
process
.
destroy
();
def
destroy
()
{
isDestroyed
=
true
guardThread
.
interrupt
()
process
.
destroy
()
try
{
guardThread
.
join
();
}
catch
(
InterruptedException
ignored
)
{
guardThread
.
join
()
}
catch
{
case
ignored
:
InterruptedException
=>
}
}
@Override
public
int
exitValue
()
{
throw
new
UnsupportedOperationException
();
def
exitValue
:
Int
=
{
throw
new
UnsupportedOperationException
}
@Override
public
InputStream
getErrorStream
()
{
throw
new
UnsupportedOperationException
();
def
getErrorStream
:
InputStream
=
{
throw
new
UnsupportedOperationException
}
@Override
public
InputStream
getInputStream
()
{
throw
new
UnsupportedOperationException
();
def
getInputStream
:
InputStream
=
{
throw
new
UnsupportedOperationException
}
@Override
public
OutputStream
getOutputStream
()
{
throw
new
UnsupportedOperationException
();
def
getOutputStream
:
OutputStream
=
{
throw
new
UnsupportedOperationException
}
@Override
public
int
waitFor
()
throws
InterruptedException
{
guardThread
.
join
();
return
0
;
@throws
(
classOf
[
InterruptedException
])
def
waitFor
:
Int
=
{
guardThread
.
join
()
0
}
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment