Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
0d1f232f
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
0d1f232f
编写于
6月 15, 2012
作者:
M
mullan
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
32e060b0
818809d7
变更
11
显示空白变更内容
内联
并排
Showing
11 changed file
with
378 addition
and
179 deletion
+378
-179
src/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java
...e/classes/com/sun/rowset/internal/CachedRowSetWriter.java
+132
-93
src/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java
...sses/com/sun/rowset/internal/XmlReaderContentHandler.java
+1
-0
src/share/classes/java/util/HashMap.java
src/share/classes/java/util/HashMap.java
+2
-3
src/share/classes/java/util/Hashtable.java
src/share/classes/java/util/Hashtable.java
+9
-11
src/share/classes/java/util/WeakHashMap.java
src/share/classes/java/util/WeakHashMap.java
+2
-4
src/share/classes/java/util/concurrent/ConcurrentHashMap.java
...share/classes/java/util/concurrent/ConcurrentHashMap.java
+1
-3
src/share/demo/jvmti/hprof/hprof_table.c
src/share/demo/jvmti/hprof/hprof_table.c
+6
-5
src/solaris/demo/jvmti/hprof/hprof_md.c
src/solaris/demo/jvmti/hprof/hprof_md.c
+5
-0
src/windows/native/sun/nio/ch/SocketDispatcher.c
src/windows/native/sun/nio/ch/SocketDispatcher.c
+38
-25
test/java/nio/channels/SocketChannel/ShortWrite.java
test/java/nio/channels/SocketChannel/ShortWrite.java
+136
-0
test/sun/security/krb5/auto/TcpTimeout.java
test/sun/security/krb5/auto/TcpTimeout.java
+46
-35
未找到文件。
src/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java
浏览文件 @
0d1f232f
/*
* Copyright (c) 2003, 201
0
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 201
2
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -828,39 +828,55 @@ public class CachedRowSetWriter implements TransactionalWriter, Serializable {
*/
private
boolean
insertNewRow
(
CachedRowSet
crs
,
PreparedStatement
pstmt
,
CachedRowSetImpl
crsRes
)
throws
SQLException
{
int
i
=
0
;
int
icolCount
=
crs
.
getMetaData
().
getColumnCount
();
boolean
returnVal
=
false
;
PreparedStatement
pstmtSel
=
con
.
prepareStatement
(
selectCmd
,
ResultSet
.
TYPE_SCROLL_SENSITIVE
,
ResultSet
.
CONCUR_READ_ONLY
);
ResultSet
rs
,
rs2
=
null
;
DatabaseMetaData
dbmd
=
con
.
getMetaData
();
rs
=
pstmtSel
.
executeQuery
();
String
table
=
crs
.
getTableName
();
rs2
=
dbmd
.
getPrimaryKeys
(
null
,
null
,
table
);
String
[]
primaryKeys
=
new
String
[
icolCount
];
try
(
PreparedStatement
pstmtSel
=
con
.
prepareStatement
(
selectCmd
,
ResultSet
.
TYPE_SCROLL_SENSITIVE
,
ResultSet
.
CONCUR_READ_ONLY
);
ResultSet
rs
=
pstmtSel
.
executeQuery
();
ResultSet
rs2
=
con
.
getMetaData
().
getPrimaryKeys
(
null
,
null
,
crs
.
getTableName
())
)
{
ResultSetMetaData
rsmd
=
crs
.
getMetaData
();
int
icolCount
=
rsmd
.
getColumnCount
();
String
[]
primaryKeys
=
new
String
[
icolCount
];
int
k
=
0
;
while
(
rs2
.
next
())
{
String
pkcolname
=
rs2
.
getString
(
"COLUMN_NAME"
);
primaryKeys
[
k
]
=
pkcolname
;
while
(
rs2
.
next
())
{
primaryKeys
[
k
]
=
rs2
.
getString
(
"COLUMN_NAME"
);
k
++;
}
if
(
rs
.
next
())
{
for
(
int
j
=
0
;
j
<
primaryKeys
.
length
;
j
++)
{
if
(
primaryKeys
[
j
]
!=
null
)
{
if
(
crs
.
getObject
(
primaryKeys
[
j
])
==
null
){
if
(
rs
.
next
())
{
for
(
String
pkName
:
primaryKeys
)
{
if
(!
isPKNameValid
(
pkName
,
rsmd
))
{
/* We came here as one of the the primary keys
* of the table is not present in the cached
* rowset object, it should be an autoincrement column
* and not included while creating CachedRowSet
* Object, proceed to check for other primary keys
*/
continue
;
}
Object
crsPK
=
crs
.
getObject
(
pkName
);
if
(
crsPK
==
null
)
{
/*
* It is possible that the PK is null on some databases
* and will be filled in at insert time (MySQL for example)
*/
break
;
}
String
crsPK
=
(
crs
.
getObject
(
primaryKeys
[
j
])).
toString
();
String
rsPK
=
(
rs
.
getObject
(
primaryKeys
[
j
])
).
toString
();
if
(
crsPK
.
equals
(
rsPK
))
{
String
rsPK
=
rs
.
getObject
(
pkName
).
toString
();
if
(
crsPK
.
toString
()
.
equals
(
rsPK
))
{
returnVal
=
true
;
this
.
crsResolve
.
moveToInsertRow
();
for
(
i
=
1
;
i
<=
icolCount
;
i
++)
{
for
(
int
i
=
1
;
i
<=
icolCount
;
i
++)
{
String
colname
=
(
rs
.
getMetaData
()).
getColumnName
(
i
);
if
(
colname
.
equals
(
primaryKeys
[
j
]
))
if
(
colname
.
equals
(
pkName
))
this
.
crsResolve
.
updateObject
(
i
,
rsPK
);
else
this
.
crsResolve
.
updateNull
(
i
);
...
...
@@ -870,12 +886,13 @@ public class CachedRowSetWriter implements TransactionalWriter, Serializable {
}
}
}
}
if
(
returnVal
)
if
(
returnVal
)
{
return
returnVal
;
}
try
{
for
(
i
=
1
;
i
<=
icolCount
;
i
++)
{
for
(
int
i
=
1
;
i
<=
icolCount
;
i
++)
{
Object
obj
=
crs
.
getObject
(
i
);
if
(
obj
!=
null
)
{
pstmt
.
setObject
(
i
,
obj
);
...
...
@@ -884,20 +901,20 @@ public class CachedRowSetWriter implements TransactionalWriter, Serializable {
}
}
i
=
pstmt
.
executeUpdate
();
pstmt
.
executeUpdate
();
return
false
;
}
catch
(
SQLException
ex
)
{
/*
*
/
*
* Cursor will come here if executeUpdate fails.
* There can be many reasons why the insertion failed,
* one can be violation of primary key.
* Hence we cannot exactly identify why the insertion failed
* Present the current row as a null row to the us
er.
*
*/
* Hence we cannot exactly identify why the insertion failed,
* present the current row as a null row to the call
er.
*/
this
.
crsResolve
.
moveToInsertRow
();
for
(
i
=
1
;
i
<=
icolCount
;
i
++)
{
for
(
int
i
=
1
;
i
<=
icolCount
;
i
++)
{
this
.
crsResolve
.
updateNull
(
i
);
}
...
...
@@ -907,6 +924,7 @@ public class CachedRowSetWriter implements TransactionalWriter, Serializable {
return
true
;
}
}
}
/**
* Deletes the row in the underlying data source that corresponds to
...
...
@@ -1437,4 +1455,25 @@ public class CachedRowSetWriter implements TransactionalWriter, Serializable {
}
static
final
long
serialVersionUID
=-
8506030970299413976L
;
/**
* Validate whether the Primary Key is known to the CachedRowSet. If it is
* not, it is an auto-generated key
* @param pk - Primary Key to validate
* @param rsmd - ResultSetMetadata for the RowSet
* @return true if found, false otherwise (auto generated key)
*/
private
boolean
isPKNameValid
(
String
pk
,
ResultSetMetaData
rsmd
)
throws
SQLException
{
boolean
isValid
=
false
;
int
cols
=
rsmd
.
getColumnCount
();
for
(
int
i
=
1
;
i
<=
cols
;
i
++)
{
String
colName
=
rsmd
.
getColumnClassName
(
i
);
if
(
colName
.
equalsIgnoreCase
(
pk
))
{
isValid
=
true
;
break
;
}
}
return
isValid
;
}
}
src/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java
浏览文件 @
0d1f232f
...
...
@@ -764,6 +764,7 @@ public class XmlReaderContentHandler extends DefaultHandler {
rs
.
next
();
rs
.
setOriginalRow
();
applyUpdates
();
rs
.
deleteRow
();
}
catch
(
SQLException
ex
)
{
throw
new
SAXException
(
MessageFormat
.
format
(
resBundle
.
handleGetObject
(
"xmlrch.errdel"
).
toString
()
,
ex
.
getMessage
()));
}
...
...
src/share/classes/java/util/HashMap.java
浏览文件 @
0d1f232f
...
...
@@ -288,12 +288,11 @@ public class HashMap<K,V>
* in lower bits.
*/
final
int
hash
(
Object
k
)
{
int
h
=
hashSeed
;
if
(
k
instanceof
String
)
{
return
((
String
)
k
).
hash32
();
return
((
String
)
k
).
hash32
();
}
h
^=
k
.
hashCode
();
int
h
=
hashSeed
^
k
.
hashCode
();
// This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded
...
...
src/share/classes/java/util/Hashtable.java
浏览文件 @
0d1f232f
...
...
@@ -194,12 +194,11 @@ public class Hashtable<K,V>
transient
final
int
hashSeed
=
sun
.
misc
.
Hashing
.
randomHashSeed
(
this
);
private
int
hash
(
Object
k
)
{
int
h
=
hashSeed
;
if
(
k
instanceof
String
)
{
return
((
String
)
k
).
hash32
();
}
else
{
h
^=
k
.
hashCode
();
}
int
h
=
hashSeed
^
k
.
hashCode
();
// This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded
...
...
@@ -207,7 +206,6 @@ public class Hashtable<K,V>
h
^=
(
h
>>>
20
)
^
(
h
>>>
12
);
return
h
^
(
h
>>>
7
)
^
(
h
>>>
4
);
}
}
/**
* Constructs a new, empty hashtable with the specified initial
...
...
@@ -1015,7 +1013,7 @@ public class Hashtable<K,V>
*/
private
static
class
Entry
<
K
,
V
>
implements
Map
.
Entry
<
K
,
V
>
{
final
int
hash
;
K
key
;
final
K
key
;
V
value
;
Entry
<
K
,
V
>
next
;
...
...
src/share/classes/java/util/WeakHashMap.java
浏览文件 @
0d1f232f
...
...
@@ -295,13 +295,11 @@ public class WeakHashMap<K,V>
* otherwise encounter collisions for hashCodes that do not differ
* in lower bits.
*/
int
hash
(
Object
k
)
{
int
h
=
hashSeed
;
final
int
hash
(
Object
k
)
{
if
(
k
instanceof
String
)
{
return
((
String
)
k
).
hash32
();
}
else
{
h
^=
k
.
hashCode
();
}
int
h
=
hashSeed
^
k
.
hashCode
();
// This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded
...
...
src/share/classes/java/util/concurrent/ConcurrentHashMap.java
浏览文件 @
0d1f232f
...
...
@@ -269,13 +269,11 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V>
* differ in lower or upper bits.
*/
private
int
hash
(
Object
k
)
{
int
h
=
hashSeed
;
if
(
k
instanceof
String
)
{
return
((
String
)
k
).
hash32
();
}
h
^=
k
.
hashCode
();
int
h
=
hashSeed
^
k
.
hashCode
();
// Spread bits to regularize both segment and index locations,
// using variant of single-word Wang/Jenkins hash.
...
...
src/share/demo/jvmti/hprof/hprof_table.c
浏览文件 @
0d1f232f
...
...
@@ -120,7 +120,7 @@ typedef struct LookupTable {
TableIndex
table_incr
;
/* Suggested increment size. */
TableIndex
hash_bucket_count
;
/* Number of hash buckets. */
int
elem_size
;
/* Size of element. */
int
info_size
;
/* Size of info structure. */
int
info_size
;
/* Size of info structure
(can be 0)
. */
void
*
freed_bv
;
/* Freed element bit vector */
int
freed_count
;
/* Count of freed'd elements */
TableIndex
freed_start
;
/* First freed in table */
...
...
@@ -208,9 +208,6 @@ get_info(LookupTable *ltable, TableIndex index)
{
TableElement
*
element
;
if
(
ltable
->
info_size
==
0
)
{
return
NULL
;
}
element
=
(
TableElement
*
)
ELEMENT_PTR
(
ltable
,
index
);
return
element
->
info
;
}
...
...
@@ -760,7 +757,11 @@ table_walk_items(LookupTable *ltable, LookupTableIterator func, void* arg)
void
*
info
;
get_key
(
ltable
,
index
,
&
key_ptr
,
&
key_len
);
if
(
ltable
->
info_size
==
0
)
{
info
=
NULL
;
}
else
{
info
=
get_info
(
ltable
,
index
);
}
(
*
func
)(
SANITY_ADD_HARE
(
index
,
ltable
->
hare
),
key_ptr
,
key_len
,
info
,
arg
);
if
(
is_freed_entry
(
ltable
,
index
)
)
{
fcount
++
;
...
...
src/solaris/demo/jvmti/hprof/hprof_md.c
浏览文件 @
0d1f232f
...
...
@@ -119,9 +119,13 @@ md_connect(char *hostname, unsigned short port)
/* create a socket */
fd
=
socket
(
AF_INET
,
SOCK_STREAM
,
0
);
if
(
fd
<
0
)
{
return
-
1
;
}
/* find remote host's addr from name */
if
((
hentry
=
gethostbyname
(
hostname
))
==
NULL
)
{
(
void
)
close
(
fd
);
return
-
1
;
}
(
void
)
memset
((
char
*
)
&
s
,
0
,
sizeof
(
s
));
...
...
@@ -134,6 +138,7 @@ md_connect(char *hostname, unsigned short port)
/* now try connecting */
if
(
-
1
==
connect
(
fd
,
(
struct
sockaddr
*
)
&
s
,
sizeof
(
s
)))
{
(
void
)
close
(
fd
);
return
0
;
}
return
fd
;
...
...
src/windows/native/sun/nio/ch/SocketDispatcher.c
浏览文件 @
0d1f232f
...
...
@@ -141,15 +141,18 @@ Java_sun_nio_ch_SocketDispatcher_readv0(JNIEnv *env, jclass clazz, jobject fdo,
JNIEXPORT
jint
JNICALL
Java_sun_nio_ch_SocketDispatcher_write0
(
JNIEnv
*
env
,
jclass
clazz
,
jobject
fdo
,
jlong
address
,
jint
len
)
jlong
address
,
jint
total
)
{
/* set up */
int
i
=
0
;
DWORD
written
=
0
;
jint
count
=
0
;
jint
fd
=
fdval
(
env
,
fdo
);
WSABUF
buf
;
do
{
/* limit size */
jint
len
=
total
-
count
;
if
(
len
>
MAX_BUFFER_SIZE
)
len
=
MAX_BUFFER_SIZE
;
...
...
@@ -157,7 +160,7 @@ Java_sun_nio_ch_SocketDispatcher_write0(JNIEnv *env, jclass clazz, jobject fdo,
buf
.
buf
=
(
char
*
)
address
;
buf
.
len
=
(
u_long
)
len
;
/* read into the buffers
*/
/* write from the buffer
*/
i
=
WSASend
((
SOCKET
)
fd
,
/* Socket */
&
buf
,
/* pointers to the buffers */
(
DWORD
)
1
,
/* number of buffers to process */
...
...
@@ -167,6 +170,10 @@ Java_sun_nio_ch_SocketDispatcher_write0(JNIEnv *env, jclass clazz, jobject fdo,
0
);
/* no completion routine */
if
(
i
==
SOCKET_ERROR
)
{
if
(
count
>
0
)
{
/* can't throw exception when some bytes have been written */
break
;
}
else
{
int
theErr
=
(
jint
)
WSAGetLastError
();
if
(
theErr
==
WSAEWOULDBLOCK
)
{
return
IOS_UNAVAILABLE
;
...
...
@@ -174,8 +181,14 @@ Java_sun_nio_ch_SocketDispatcher_write0(JNIEnv *env, jclass clazz, jobject fdo,
JNU_ThrowIOExceptionWithLastError
(
env
,
"Write failed"
);
return
IOS_THROWN
;
}
}
count
+=
written
;
address
+=
written
;
}
while
((
count
<
total
)
&&
(
written
==
MAX_BUFFER_SIZE
));
return
co
nvertReturnVal
(
env
,
(
jint
)
written
,
JNI_FALSE
)
;
return
co
unt
;
}
JNIEXPORT
jlong
JNICALL
...
...
test/java/nio/channels/SocketChannel/ShortWrite.java
0 → 100644
浏览文件 @
0d1f232f
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 7176630
* @summary Check for short writes on SocketChannels configured in blocking mode
*/
import
java.net.*
;
import
java.nio.ByteBuffer
;
import
java.nio.channels.*
;
import
java.util.concurrent.*
;
import
java.util.Random
;
import
java.util.zip.CRC32
;
public
class
ShortWrite
{
static
final
Random
rand
=
new
Random
();
/**
* Returns a checksum on the remaining bytes in the given buffer.
*/
static
long
computeChecksum
(
ByteBuffer
bb
)
{
CRC32
crc32
=
new
CRC32
();
crc32
.
update
(
bb
);
return
crc32
.
getValue
();
}
/**
* A task that reads the expected number of bytes and returns the CRC32
* of those bytes.
*/
static
class
Reader
implements
Callable
<
Long
>
{
final
SocketChannel
sc
;
final
ByteBuffer
buf
;
Reader
(
SocketChannel
sc
,
int
expectedSize
)
{
this
.
sc
=
sc
;
this
.
buf
=
ByteBuffer
.
allocate
(
expectedSize
);
}
public
Long
call
()
throws
Exception
{
while
(
buf
.
hasRemaining
())
{
int
n
=
sc
.
read
(
buf
);
if
(
n
==
-
1
)
throw
new
RuntimeException
(
"Premature EOF encountered"
);
}
buf
.
flip
();
return
computeChecksum
(
buf
);
}
}
/**
* Run test with a write of the given number of bytes.
*/
static
void
test
(
ExecutorService
pool
,
SocketChannel
source
,
SocketChannel
sink
,
int
size
)
throws
Exception
{
System
.
out
.
println
(
size
);
// random bytes in the buffer
ByteBuffer
buf
=
ByteBuffer
.
allocate
(
size
);
rand
.
nextBytes
(
buf
.
array
());
// submit task to read the bytes
Future
<
Long
>
result
=
pool
.
submit
(
new
Reader
(
sink
,
size
));
// write the bytes
int
n
=
source
.
write
(
buf
);
if
(
n
!=
size
)
throw
new
RuntimeException
(
"Short write detected"
);
// check the bytes that were received match
buf
.
rewind
();
long
expected
=
computeChecksum
(
buf
);
long
actual
=
result
.
get
();
if
(
actual
!=
expected
)
throw
new
RuntimeException
(
"Checksum did not match"
);
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
ExecutorService
pool
=
Executors
.
newSingleThreadExecutor
();
try
{
try
(
ServerSocketChannel
ssc
=
ServerSocketChannel
.
open
())
{
ssc
.
bind
(
new
InetSocketAddress
(
0
));
InetAddress
lh
=
InetAddress
.
getLocalHost
();
int
port
=
ssc
.
socket
().
getLocalPort
();
SocketAddress
sa
=
new
InetSocketAddress
(
lh
,
port
);
try
(
SocketChannel
source
=
SocketChannel
.
open
(
sa
);
SocketChannel
sink
=
ssc
.
accept
())
{
// run tests on sizes around 128k as that is the problem
// area on Windows.
int
BOUNDARY
=
128
*
1024
;
for
(
int
size
=(
BOUNDARY
-
2
);
size
<=(
BOUNDARY
+
2
);
size
++)
{
test
(
pool
,
source
,
sink
,
size
);
}
// run tests on random sizes
for
(
int
i
=
0
;
i
<
20
;
i
++)
{
int
size
=
rand
.
nextInt
(
1024
*
1024
);
test
(
pool
,
source
,
sink
,
size
);
}
}
}
}
finally
{
pool
.
shutdown
();
}
}
}
test/sun/security/krb5/auto/TcpTimeout.java
浏览文件 @
0d1f232f
...
...
@@ -48,8 +48,14 @@ public class TcpTimeout {
k
.
addPrincipalRandKey
(
"krbtgt/"
+
OneKDC
.
REALM
);
// Start two listener that does not communicate, simulate timeout
int
p1
=
new
ServerSocket
(
0
).
getLocalPort
();
int
p2
=
new
ServerSocket
(
0
).
getLocalPort
();
ServerSocket
ss1
=
null
;
ServerSocket
ss2
=
null
;
try
{
ss1
=
new
ServerSocket
(
0
);
ss2
=
new
ServerSocket
(
0
);
int
p1
=
ss1
.
getLocalPort
();
int
p2
=
ss2
.
getLocalPort
();
FileWriter
fw
=
new
FileWriter
(
"alternative-krb5.conf"
);
...
...
@@ -65,7 +71,8 @@ public class TcpTimeout {
"}\n"
);
fw
.
close
();
System
.
setProperty
(
"java.security.krb5.conf"
,
"alternative-krb5.conf"
);
System
.
setProperty
(
"java.security.krb5.conf"
,
"alternative-krb5.conf"
);
Config
.
refresh
();
System
.
out
.
println
(
"Ports opened on "
+
p1
+
", "
+
p2
+
", "
+
p3
);
...
...
@@ -92,5 +99,9 @@ public class TcpTimeout {
if
(
count
!=
0
)
{
throw
new
Exception
(
"Retry count is "
+
count
+
" less"
);
}
}
finally
{
if
(
ss1
!=
null
)
ss1
.
close
();
if
(
ss2
!=
null
)
ss2
.
close
();
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录