Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
5c4f8212
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看板
提交
5c4f8212
编写于
10月 22, 2013
作者:
A
alanb
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
7074436: (sc) SocketChannel can do short gathering writes when channel configured blocking (win)
Reviewed-by: chegar
上级
11ae5e94
变更
2
显示空白变更内容
内联
并排
Showing
2 changed file
with
131 addition
and
38 deletion
+131
-38
src/windows/native/sun/nio/ch/SocketDispatcher.c
src/windows/native/sun/nio/ch/SocketDispatcher.c
+44
-23
test/java/nio/channels/SocketChannel/ShortWrite.java
test/java/nio/channels/SocketChannel/ShortWrite.java
+87
-15
未找到文件。
src/windows/native/sun/nio/ch/SocketDispatcher.c
浏览文件 @
5c4f8212
...
...
@@ -192,45 +192,66 @@ Java_sun_nio_ch_SocketDispatcher_writev0(JNIEnv *env, jclass clazz,
jobject
fdo
,
jlong
address
,
jint
len
)
{
/* set up */
int
i
=
0
;
int
next_index
,
next_offset
,
ret
=
0
;
DWORD
written
=
0
;
jint
fd
=
fdval
(
env
,
fdo
);
struct
iovec
*
iovp
=
(
struct
iovec
*
)
address
;
WSABUF
*
bufs
=
malloc
(
len
*
sizeof
(
WSABUF
));
j
int
rem
=
MAX_BUFFER_SIZE
;
j
long
count
=
0
;
if
(
bufs
==
0
)
{
JNU_ThrowOutOfMemoryError
(
env
,
0
);
return
IOS_THROWN
;
}
/* copy iovec into WSABUF */
for
(
i
=
0
;
i
<
len
;
i
++
)
{
jint
iov_len
=
iovp
[
i
].
iov_len
;
if
(
iov_len
>
rem
)
// next buffer and offset to consume
next_index
=
0
;
next_offset
=
0
;
while
(
next_index
<
len
)
{
DWORD
buf_count
=
0
;
/* Prepare the WSABUF array to a maximum total size of MAX_BUFFER_SIZE */
jint
rem
=
MAX_BUFFER_SIZE
;
while
(
next_index
<
len
&&
rem
>
0
)
{
jint
iov_len
=
iovp
[
next_index
].
iov_len
-
next_offset
;
char
*
ptr
=
(
char
*
)
iovp
[
next_index
].
iov_base
;
ptr
+=
next_offset
;
if
(
iov_len
>
rem
)
{
iov_len
=
rem
;
bufs
[
i
].
buf
=
(
char
*
)
iovp
[
i
].
iov_base
;
bufs
[
i
].
len
=
(
u_long
)
iov_len
;
rem
-=
iov_len
;
if
(
rem
==
0
)
{
len
=
i
+
1
;
break
;
next_offset
+=
rem
;
}
else
{
next_index
++
;
next_offset
=
0
;
}
bufs
[
buf_count
].
buf
=
ptr
;
bufs
[
buf_count
].
len
=
(
u_long
)
iov_len
;
buf_count
++
;
rem
-=
iov_len
;
}
/* read into
the buffers */
i
=
WSASend
((
SOCKET
)
fd
,
/* Socket */
/* write
the buffers */
ret
=
WSASend
((
SOCKET
)
fd
,
/* Socket */
bufs
,
/* pointers to the buffers */
(
DWORD
)
len
,
/* number of buffers to process */
buf_count
,
/* number of buffers to process */
&
written
,
/* receives number of bytes written */
0
,
/* no flags */
0
,
/* no overlapped sockets */
0
);
/* no completion routine */
if
(
ret
==
SOCKET_ERROR
)
{
break
;
}
count
+=
written
;
}
/* clean up */
free
(
bufs
);
if
(
i
!
=
0
)
{
if
(
ret
==
SOCKET_ERROR
&&
count
=
=
0
)
{
int
theErr
=
(
jint
)
WSAGetLastError
();
if
(
theErr
==
WSAEWOULDBLOCK
)
{
return
IOS_UNAVAILABLE
;
...
...
@@ -239,7 +260,7 @@ Java_sun_nio_ch_SocketDispatcher_writev0(JNIEnv *env, jclass clazz,
return
IOS_THROWN
;
}
return
convertLongReturnVal
(
env
,
(
jlong
)
written
,
JNI_FALSE
);
return
convertLongReturnVal
(
env
,
count
,
JNI_FALSE
);
}
JNIEXPORT
void
JNICALL
...
...
test/java/nio/channels/SocketChannel/ShortWrite.java
浏览文件 @
5c4f8212
...
...
@@ -22,7 +22,7 @@
*/
/* @test
* @bug 7176630
* @bug 7176630
7074436
* @summary Check for short writes on SocketChannels configured in blocking mode
*/
...
...
@@ -38,11 +38,12 @@ public class ShortWrite {
static
final
Random
rand
=
new
Random
();
/**
* Returns a checksum on the remaining bytes in the given buffer.
* Returns a checksum on the remaining bytes in the given buffer
s
.
*/
static
long
computeChecksum
(
ByteBuffer
bb
)
{
static
long
computeChecksum
(
ByteBuffer
...
bufs
)
{
CRC32
crc32
=
new
CRC32
();
crc32
.
update
(
bb
);
for
(
int
i
=
0
;
i
<
bufs
.
length
;
i
++)
crc32
.
update
(
bufs
[
i
]);
return
crc32
.
getValue
();
}
...
...
@@ -71,15 +72,15 @@ public class ShortWrite {
}
/**
*
Run test with a write of the
given number of bytes.
*
Exercise write(ByteBuffer) with
given number of bytes.
*/
static
void
test
(
ExecutorService
pool
,
static
void
test
1
(
ExecutorService
pool
,
SocketChannel
source
,
SocketChannel
sink
,
int
size
)
throws
Exception
{
System
.
out
.
println
(
size
);
System
.
out
.
println
(
"write(ByteBuffer), size="
+
size
);
// random bytes in the buffer
ByteBuffer
buf
=
ByteBuffer
.
allocate
(
size
);
...
...
@@ -101,6 +102,47 @@ public class ShortWrite {
throw
new
RuntimeException
(
"Checksum did not match"
);
}
/**
* Exercise write(ByteBuffer[]) with buffers of the given sizes.
*/
static
void
testN
(
ExecutorService
pool
,
SocketChannel
source
,
SocketChannel
sink
,
int
...
sizes
)
throws
Exception
{
System
.
out
.
print
(
"write(ByteBuffer[]), sizes="
);
for
(
int
size:
sizes
)
System
.
out
.
print
(
size
+
" "
);
System
.
out
.
println
();
int
total
=
0
;
int
len
=
sizes
.
length
;
ByteBuffer
[]
bufs
=
new
ByteBuffer
[
len
];
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
int
size
=
sizes
[
i
];
ByteBuffer
buf
=
ByteBuffer
.
allocate
(
size
);
rand
.
nextBytes
(
buf
.
array
());
bufs
[
i
]
=
buf
;
total
+=
size
;
}
// submit task to read the bytes
Future
<
Long
>
result
=
pool
.
submit
(
new
Reader
(
sink
,
total
));
// write the bytes
long
n
=
source
.
write
(
bufs
);
if
(
n
!=
total
)
throw
new
RuntimeException
(
"Short write detected"
);
// check the bytes that were received match
for
(
int
i
=
0
;
i
<
len
;
i
++)
bufs
[
i
].
rewind
();
long
expected
=
computeChecksum
(
bufs
);
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
();
...
...
@@ -114,17 +156,47 @@ public class ShortWrite {
try
(
SocketChannel
source
=
SocketChannel
.
open
(
sa
);
SocketChannel
sink
=
ssc
.
accept
())
{
// run tests on sizes around 128k as that is the problem
// area on Windows.
// Exercise write(BufferBuffer) on sizes around 128k
int
BOUNDARY
=
128
*
1024
;
for
(
int
size
=(
BOUNDARY
-
2
);
size
<=(
BOUNDARY
+
2
);
size
++)
{
test
(
pool
,
source
,
sink
,
size
);
test
1
(
pool
,
source
,
sink
,
size
);
}
//
run tests
on random sizes
//
Exercise write(BufferBuffer)
on random sizes
for
(
int
i
=
0
;
i
<
20
;
i
++)
{
int
size
=
rand
.
nextInt
(
1024
*
1024
);
test
(
pool
,
source
,
sink
,
size
);
test1
(
pool
,
source
,
sink
,
size
);
}
// Exercise write(BufferBuffer[]) on sizes around 128k
for
(
int
i
=
BOUNDARY
-
2
;
i
<=
BOUNDARY
+
2
;
i
++)
{
testN
(
pool
,
source
,
sink
,
i
);
testN
(
pool
,
source
,
sink
,
0
,
i
);
testN
(
pool
,
source
,
sink
,
i
,
0
);
for
(
int
j
=
BOUNDARY
-
2
;
j
<=
BOUNDARY
+
2
;
j
++)
{
testN
(
pool
,
source
,
sink
,
i
,
j
);
testN
(
pool
,
source
,
sink
,
0
,
i
,
j
);
testN
(
pool
,
source
,
sink
,
i
,
0
,
j
);
testN
(
pool
,
source
,
sink
,
i
,
j
,
0
);
for
(
int
k
=
BOUNDARY
-
2
;
k
<=
BOUNDARY
+
2
;
k
++)
{
testN
(
pool
,
source
,
sink
,
i
,
j
,
k
);
testN
(
pool
,
source
,
sink
,
0
,
i
,
j
,
k
);
testN
(
pool
,
source
,
sink
,
i
,
0
,
j
,
k
);
testN
(
pool
,
source
,
sink
,
i
,
j
,
0
,
k
);
testN
(
pool
,
source
,
sink
,
i
,
j
,
k
,
0
);
}
}
}
// Exercise write(BufferBuffer[]) on random sizes
// (assumes IOV_MAX >= 8)
for
(
int
i
=
0
;
i
<
20
;
i
++)
{
int
n
=
rand
.
nextInt
(
9
);
int
[]
sizes
=
new
int
[
n
];
for
(
int
j
=
0
;
j
<
n
;
j
++)
{
sizes
[
j
]
=
rand
.
nextInt
(
1024
*
1024
);
}
testN
(
pool
,
source
,
sink
,
sizes
);
}
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录