Win32 API 日本語リファレンス
ホームNetworking.WinSock › WSAPoll

WSAPoll

関数
複数ソケットの状態変化をポーリングで監視する。
DLLWS2_32.dll呼出規約winapiSetLastErrorあり対応OSWindows 8.1 以降

シグネチャ

// WS2_32.dll
#include <windows.h>

INT WSAPoll(
    WSAPOLLFD* fdArray,
    DWORD fds,
    INT timeout
);

パラメーター

名前方向説明
fdArrayWSAPOLLFD*inout状態を要求する socket のセットを指定する、1 つ以上の POLLFD 構造体の配列です。この配列には、有効な socket を持つ構造体が少なくとも 1 つ含まれている必要があります。戻り時に、このパラメーターは、状態照会条件に一致する各 socket について revents 状態フラグメンバーが設定された、更新済みの socket を受け取ります。
fdsDWORDinfdarray 内の WSAPOLLFD 構造体の数です。これは、状態を要求する socket の数と必ずしも一致しません。
timeoutINTin

待機動作を指定する値で、次の値に基づきます。

意味
0 より大きい 待機する時間 (ミリ秒単位)。
0 即座に戻ります。
0 より小さい 無期限に待機します。

戻り値の型: INT

公式ドキュメント

WSAPoll 関数は、1 つ以上の socket の状態を判定します。

戻り値

次のいずれかの値を返します。

戻り値 説明
0 タイマーが満了する前に、照会された状態にある socket がありませんでした。
0 より大きい fdarray 内の要素のうち、POLLFD 構造体の revents メンバーが 0 以外である要素の数です。
SOCKET_ERROR エラーが発生しました。WSAGetLastError 関数を呼び出して、拡張エラーコードを取得してください。
拡張エラーコード 意味
WSAENETDOWN
ネットワークサブシステムに障害が発生しました。
WSAEFAULT
ユーザー入力パラメーターの読み取り中に例外が発生しました。
WSAEINVAL
無効なパラメーターが渡されました。このエラーは、socket の状態を要求する際に、fdarray パラメーターが指す WSAPOLLFD 構造体に問題がある場合に返されます。また、fdarray パラメーターが指すいずれの WSAPOLLFD 構造体の fd メンバーに指定された socket も有効でなかった場合にも、このエラーが返されます。
WSAENOBUFS
関数が十分なメモリを割り当てられませんでした。

解説(Remarks)

WSAPoll 関数は、Windows Vista 以降で定義されています。

fdarray パラメーターは WSAPOLLFD 構造体を指します。アプリケーションは、WSAPOLLFD 構造体の events メンバーに適切なフラグを設定して、対応する各 socket について要求する状態の種類を指定します。WSAPoll 関数は、socket の状態を WSAPOLLFD 構造体の revents メンバーで返します。

各 socket について、呼び出し元は読み取りまたは書き込み状態に関する情報を要求できます。エラー条件は常に返されるため、それらに関する情報を要求する必要はありません。

状態が要求された socket は、fdarray パラメーターが指す WSAPOLLFD 構造体で報告されます。これらの条件を満たさず、エラー条件もないすべての socket は、対応する revents メンバーが 0 に設定されます。

ある socket の状態を要求する際、その socket について WSAPOLLFD 構造体には、次のフラグを組み合わせて設定できます。

フラグ 説明
POLLPRI 優先データをブロックせずに読み取れます。このフラグは Microsoft Winsock プロバイダーではサポートされていません。
POLLRDBAND 優先帯域 (帯域外) データをブロックせずに読み取れます。
POLLRDNORM 通常データをブロックせずに読み取れます。
POLLWRNORM 通常データをブロックせずに書き込めます。

POLLIN フラグは、POLLRDNORMPOLLRDBAND のフラグ値の組み合わせとして定義されます。POLLOUT フラグは、POLLWRNORM フラグ値と同じものとして定義されます。

WSAPOLLFD 構造体には、Winsock プロバイダーがサポートする上記フラグの組み合わせのみを含める必要があります。それ以外の値はエラーとみなされ、WSAPollSOCKET_ERROR を返します。続いて WSAGetLastError 関数を呼び出すと、拡張エラーコード WSAEINVAL が取得されます。Microsoft Winsock プロバイダーで socket に POLLPRI フラグが設定されている場合、WSAPoll 関数は失敗します。

socket の状態を示すために、fdarray パラメーターが指す WSAPOLLFD 構造体の revents メンバーには、次のフラグが設定されることがあります。

フラグ 説明
POLLERR エラーが発生しました。
POLLHUP ストリーム指向の接続が切断または中断されました。
POLLNVAL 無効な socket が使用されました。
POLLPRI 優先データをブロックせずに読み取れます。このフラグは Microsoft Winsock プロバイダーでは返されません。
POLLRDBAND 優先帯域 (帯域外) データをブロックせずに読み取れます。
POLLRDNORM 通常データをブロックせずに読み取れます。
POLLWRNORM 通常データをブロックせずに書き込めます。

TCP および UDP socket に関して:

fdarray 内の要素 (socket ではない) の数は nfds で示されます。fdarray のメンバーのうち、fd メンバーが負の値に設定されているものは無視され、戻り時にその reventsPOLLNVAL に設定されます。この動作は、固定の fdarray 割り当てを維持し、未使用エントリを削除するために配列を圧縮したり、メモリを再割り当てしたりしないアプリケーションにとって有用です。WSAPoll を呼び出す前に、いずれの要素についても revents をクリアする必要はありません。

timeout 引数は、関数が戻る前にどれだけ待機するかを指定します。正の値は、戻る前に待機するミリ秒数を表します。値が 0 の場合、WSAPoll は即座に戻ります。負の値は、WSAPoll が無期限に待機することを示します。

注意 timeout パラメーターを負の数に設定して WSAPoll のようなブロッキング Winsock 呼び出しを発行する場合、Winsock は呼び出しが完了する前にネットワークイベントを待機する必要があることがあります。この状況で Winsock はアラート可能な待機を実行し、同じスレッドにスケジュールされた非同期プロシージャ呼び出し (APC) によって中断されることがあります。同じスレッドで進行中のブロッキング Winsock 呼び出しを中断した APC 内から別のブロッキング Winsock 呼び出しを発行すると、未定義の動作につながり、Winsock クライアントが行ってはなりません。
注意 Windows 10 バージョン 2004 以降では、TCP socket の接続が失敗した場合、(POLLHUP \| POLLERR \| POLLWRNORM) が示されます。

Windows 8.1 および Windows Server 2012 R2: この関数は、Windows 8.1、Windows Server 2012 R2 以降の Windows ストアアプリでサポートされています。

出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)

各言語での呼び出し定義

// WS2_32.dll
#include <windows.h>

INT WSAPoll(
    WSAPOLLFD* fdArray,
    DWORD fds,
    INT timeout
);
[DllImport("WS2_32.dll", SetLastError = true, ExactSpelling = true)]
static extern int WSAPoll(
    IntPtr fdArray,   // WSAPOLLFD* in/out
    uint fds,   // DWORD
    int timeout   // INT
);
<DllImport("WS2_32.dll", SetLastError:=True, ExactSpelling:=True)>
Public Shared Function WSAPoll(
    fdArray As IntPtr,   ' WSAPOLLFD* in/out
    fds As UInteger,   ' DWORD
    timeout As Integer   ' INT
) As Integer
End Function
' fdArray : WSAPOLLFD* in/out
' fds : DWORD
' timeout : INT
Declare PtrSafe Function WSAPoll Lib "ws2_32" ( _
    ByVal fdArray As LongPtr, _
    ByVal fds As Long, _
    ByVal timeout As Long) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

WSAPoll = ctypes.windll.ws2_32.WSAPoll
WSAPoll.restype = ctypes.c_int
WSAPoll.argtypes = [
    ctypes.c_void_p,  # fdArray : WSAPOLLFD* in/out
    wintypes.DWORD,  # fds : DWORD
    ctypes.c_int,  # timeout : INT
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))
require 'fiddle'
require 'fiddle/import'

lib = Fiddle.dlopen('WS2_32.dll')
WSAPoll = Fiddle::Function.new(
  lib['WSAPoll'],
  [
    Fiddle::TYPE_VOIDP,  # fdArray : WSAPOLLFD* in/out
    -Fiddle::TYPE_INT,  # fds : DWORD
    Fiddle::TYPE_INT,  # timeout : INT
  ],
  Fiddle::TYPE_INT)
#[link(name = "ws2_32")]
extern "system" {
    fn WSAPoll(
        fdArray: *mut WSAPOLLFD,  // WSAPOLLFD* in/out
        fds: u32,  // DWORD
        timeout: i32  // INT
    ) -> i32;
}
// crates: windows-sys provides ready-made bindings for this API.
$sig = @"
[DllImport("WS2_32.dll", SetLastError = true)]
public static extern int WSAPoll(IntPtr fdArray, uint fds, int timeout);
"@
$api = Add-Type -MemberDefinition $sig -Name 'WS2_32_WSAPoll' -Namespace Win32 -PassThru
# $api::WSAPoll(fdArray, fds, timeout)
#uselib "WS2_32.dll"
#func global WSAPoll "WSAPoll" sptr, sptr, sptr
; WSAPoll varptr(fdArray), fds, timeout   ; 戻り値は stat
; fdArray : WSAPOLLFD* in/out -> "sptr"
; fds : DWORD -> "sptr"
; timeout : INT -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。
出力引数:
#uselib "WS2_32.dll"
#cfunc global WSAPoll "WSAPoll" var, int, int
; res = WSAPoll(fdArray, fds, timeout)
; fdArray : WSAPOLLFD* in/out -> "var"
; fds : DWORD -> "int"
; timeout : INT -> "int"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
出力引数:
; INT WSAPoll(WSAPOLLFD* fdArray, DWORD fds, INT timeout)
#uselib "WS2_32.dll"
#cfunc global WSAPoll "WSAPoll" var, int, int
; res = WSAPoll(fdArray, fds, timeout)
; fdArray : WSAPOLLFD* in/out -> "var"
; fds : DWORD -> "int"
; timeout : INT -> "int"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
import (
	"golang.org/x/sys/windows"
	"unsafe"
)

var (
	ws2_32 = windows.NewLazySystemDLL("WS2_32.dll")
	procWSAPoll = ws2_32.NewProc("WSAPoll")
)

// fdArray (WSAPOLLFD* in/out), fds (DWORD), timeout (INT)
r1, _, err := procWSAPoll.Call(
	uintptr(fdArray),
	uintptr(fds),
	uintptr(timeout),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // INT
function WSAPoll(
  fdArray: Pointer;   // WSAPOLLFD* in/out
  fds: DWORD;   // DWORD
  timeout: Integer   // INT
): Integer; stdcall;
  external 'WS2_32.dll' name 'WSAPoll';
result := DllCall("WS2_32\WSAPoll"
    , "Ptr", fdArray   ; WSAPOLLFD* in/out
    , "UInt", fds   ; DWORD
    , "Int", timeout   ; INT
    , "Int")   ; return: INT
●WSAPoll(fdArray, fds, timeout) = DLL("WS2_32.dll", "int WSAPoll(void*, dword, int)")
# 呼び出し: WSAPoll(fdArray, fds, timeout)
# fdArray : WSAPOLLFD* in/out -> "void*"
# fds : DWORD -> "dword"
# timeout : INT -> "int"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
const std = @import("std");

extern "ws2_32" fn WSAPoll(
    fdArray: [*c]WSAPOLLFD, // WSAPOLLFD* in/out
    fds: u32, // DWORD
    timeout: i32 // INT
) callconv(std.os.windows.WINAPI) i32;
proc WSAPoll(
    fdArray: ptr WSAPOLLFD,  # WSAPOLLFD* in/out
    fds: uint32,  # DWORD
    timeout: int32  # INT
): int32 {.importc: "WSAPoll", stdcall, dynlib: "WS2_32.dll".}
pragma(lib, "ws2_32");
extern(Windows)
int WSAPoll(
    WSAPOLLFD* fdArray,   // WSAPOLLFD* in/out
    uint fds,   // DWORD
    int timeout   // INT
);
ccall((:WSAPoll, "WS2_32.dll"), stdcall, Int32,
      (Ptr{WSAPOLLFD}, UInt32, Int32),
      fdArray, fds, timeout)
# fdArray : WSAPOLLFD* in/out -> Ptr{WSAPOLLFD}
# fds : DWORD -> UInt32
# timeout : INT -> Int32
# stdcall は 32bit のみ意味を持つ(x64 では無視)。
local ffi = require("ffi")
ffi.cdef[[
int32_t WSAPoll(
    void* fdArray,
    uint32_t fds,
    int32_t timeout);
]]
local ws2_32 = ffi.load("ws2_32")
-- ws2_32.WSAPoll(fdArray, fds, timeout)
-- fdArray : WSAPOLLFD* in/out
-- fds : DWORD
-- timeout : INT
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
const koffi = require('koffi');
const lib = koffi.load('WS2_32.dll');
const WSAPoll = lib.func('__stdcall', 'WSAPoll', 'int32_t', ['void *', 'uint32_t', 'int32_t']);
// WSAPoll(fdArray, fds, timeout)
// fdArray : WSAPOLLFD* in/out -> 'void *'
// fds : DWORD -> 'uint32_t'
// timeout : INT -> 'int32_t'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。
const lib = Deno.dlopen("WS2_32.dll", {
  WSAPoll: { parameters: ["pointer", "u32", "i32"], result: "i32" },
});
// lib.symbols.WSAPoll(fdArray, fds, timeout)
// fdArray : WSAPOLLFD* in/out -> "pointer"
// fds : DWORD -> "u32"
// timeout : INT -> "i32"
// 文字列引数は "buffer"(NUL 終端のバイト列を Uint8Array で渡す)。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。
<?php
$ffi = FFI::cdef(<<<C
int32_t WSAPoll(
    void* fdArray,
    uint32_t fds,
    int32_t timeout);
C, "WS2_32.dll");
// $ffi->WSAPoll(fdArray, fds, timeout);
// fdArray : WSAPOLLFD* in/out
// fds : DWORD
// timeout : INT
// 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
// WINAPI(stdcall): x64 では呼出規約が統一されるため問題なし。x86 では __stdcall 対応のラッパが必要な場合あり。
import com.sun.jna.*;
import com.sun.jna.ptr.*;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;

public interface Ws2_32 extends StdCallLibrary {
    Ws2_32 INSTANCE = Native.load("ws2_32", Ws2_32.class);
    int WSAPoll(
        Pointer fdArray,   // WSAPOLLFD* in/out
        int fds,   // DWORD
        int timeout   // INT
    );
}
@[Link("ws2_32")]
lib LibWS2_32
  fun WSAPoll = WSAPoll(
    fdArray : WSAPOLLFD*,   # WSAPOLLFD* in/out
    fds : UInt32,   # DWORD
    timeout : Int32   # INT
  ) : Int32
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。
import 'dart:ffi';
import 'package:ffi/ffi.dart';

typedef WSAPollNative = Int32 Function(Pointer<Void>, Uint32, Int32);
typedef WSAPollDart = int Function(Pointer<Void>, int, int);
final WSAPoll = DynamicLibrary.open('WS2_32.dll')
    .lookupFunction<WSAPollNative, WSAPollDart>('WSAPoll');
// fdArray : WSAPOLLFD* in/out -> Pointer<Void>
// fds : DWORD -> Uint32
// timeout : INT -> Int32
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function WSAPoll(
  fdArray: Pointer;   // WSAPOLLFD* in/out
  fds: DWORD;   // DWORD
  timeout: Integer   // INT
): Integer; stdcall;
  external 'WS2_32.dll' name 'WSAPoll';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "WSAPoll"
  c_WSAPoll :: Ptr () -> Word32 -> Int32 -> IO Int32
-- fdArray : WSAPOLLFD* in/out -> Ptr ()
-- fds : DWORD -> Word32
-- timeout : INT -> Int32
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let wsapoll =
  foreign "WSAPoll"
    ((ptr void) @-> uint32_t @-> int32_t @-> returning int32_t)
(* fdArray : WSAPOLLFD* in/out -> (ptr void) *)
(* fds : DWORD -> uint32_t *)
(* timeout : INT -> int32_t *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)
(cffi:define-foreign-library ws2_32 (t "WS2_32.dll"))
(cffi:use-foreign-library ws2_32)

(cffi:defcfun ("WSAPoll" wsapoll :convention :stdcall) :int32
  (fd-array :pointer)   ; WSAPOLLFD* in/out
  (fds :uint32)   ; DWORD
  (timeout :int32))   ; INT
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $WSAPoll = Win32::API::More->new('WS2_32',
    'int WSAPoll(LPVOID fdArray, DWORD fds, int timeout)');
# my $ret = $WSAPoll->Call($fdArray, $fds, $timeout);
# fdArray : WSAPOLLFD* in/out -> LPVOID
# fds : DWORD -> DWORD
# timeout : INT -> int
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。

関連項目

公式の関連項目
使用する型