- created server object for handling async i/o
- implemented WaitCommEvent with the EV_RXCHAR flag - implemented GetOverlappedResult
This commit is contained in:
parent
745ec84c8b
commit
1eac1911c7
@ -2580,13 +2580,111 @@ BOOL WINAPI GetCommModemStatus(HANDLE hFile,LPDWORD lpModemStat )
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
VOID COMM_WaitCommEventService(void **args)
|
||||
{
|
||||
LPOVERLAPPED lpOverlapped = (LPOVERLAPPED)args[0];
|
||||
LPDWORD buffer = (LPDWORD)args[1];
|
||||
DWORD events = (DWORD)args[2];
|
||||
|
||||
TRACE("overlapped %p wait complete %p <- %lx\n",lpOverlapped,buffer,events);
|
||||
if(buffer)
|
||||
*buffer = events;
|
||||
|
||||
SetEvent( lpOverlapped->hEvent);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* WaitCommEvent (KERNEL32.719)
|
||||
*
|
||||
* Wait until something interesting happens on a COMM port.
|
||||
* Interesting things (events) are set by calling SetCommMask before
|
||||
* this function is called.
|
||||
*
|
||||
* RETURNS:
|
||||
* TRUE if successful
|
||||
* FALSE if failure
|
||||
*
|
||||
* The set of detected events will be written to *lpdwEventMask
|
||||
* ERROR_IO_PENDING will be returned the overlapped structure was passed
|
||||
*
|
||||
* BUGS:
|
||||
* Only supports EV_RXCHAR and EV_TXEMPTY
|
||||
*/
|
||||
BOOL WINAPI WaitCommEvent(HANDLE hFile,LPDWORD eventmask ,LPOVERLAPPED overlapped)
|
||||
BOOL WINAPI WaitCommEvent(
|
||||
HANDLE hFile, /* [I] handle of comm port to wait for */
|
||||
LPDWORD lpdwEvents, /* [O] event(s) that were detected */
|
||||
LPOVERLAPPED lpOverlapped /* [I/O] for Asynchronous waiting */
|
||||
) {
|
||||
OVERLAPPED ov;
|
||||
LPOVERLAPPED lpov;
|
||||
int ret;
|
||||
|
||||
TRACE("(%x %p %p )\n",hFile, lpdwEvents,lpOverlapped);
|
||||
|
||||
/* if there is no overlapped structure, create our own */
|
||||
if(!lpOverlapped)
|
||||
{
|
||||
ov.hEvent = CreateEventA(NULL,FALSE,FALSE,NULL);
|
||||
lpov = &ov;
|
||||
}
|
||||
else
|
||||
lpov = lpOverlapped;
|
||||
|
||||
/* check that the overlapped structure has a valid event flag */
|
||||
if ( (lpov->hEvent==0) || (lpov->hEvent == INVALID_HANDLE_VALUE) )
|
||||
{
|
||||
FIXME("(%d %p %p )\n",hFile, eventmask,overlapped);
|
||||
return TRUE;
|
||||
ERR("Couldn't create Event flag for Overlapped structure\n");
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
lpov->Internal = 0;
|
||||
lpov->InternalHigh = hFile;
|
||||
lpov->Offset = 0;
|
||||
lpov->OffsetHigh = 0;
|
||||
|
||||
/* start an ASYNCHRONOUS WaitCommEvent */
|
||||
SERVER_START_REQ
|
||||
{
|
||||
struct create_async_request *req = server_alloc_req( sizeof(*req), 0 );
|
||||
|
||||
req->file_handle = hFile;
|
||||
req->overlapped = lpov;
|
||||
req->buffer = lpdwEvents;
|
||||
req->count = 0;
|
||||
req->func = COMM_WaitCommEventService;
|
||||
req->type = ASYNC_TYPE_WAIT;
|
||||
|
||||
ret=server_call( REQ_CREATE_ASYNC );
|
||||
|
||||
lpov->Internal = req->ov_handle;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
if(ret)
|
||||
{
|
||||
if(!lpOverlapped)
|
||||
CloseHandle(lpov->hEvent);
|
||||
TRACE("server call failed.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* wait ourselves if the caller didn't give us an overlapped struct */
|
||||
if(!lpOverlapped)
|
||||
{
|
||||
GetOverlappedResult(hFile, lpov, NULL, TRUE);
|
||||
CloseHandle(lpov->hEvent);
|
||||
lpov->hEvent=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* caller wants overlapped I/O using GetOverlapped result */
|
||||
SetLastError(ERROR_IO_PENDING);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -356,7 +356,7 @@ struct get_apc_request
|
||||
OUT int type; /* function type */
|
||||
OUT VARARG(args,ptrs); /* function arguments */
|
||||
};
|
||||
enum apc_type { APC_NONE, APC_USER, APC_TIMER };
|
||||
enum apc_type { APC_NONE, APC_USER, APC_TIMER, APC_ASYNC };
|
||||
|
||||
|
||||
/* Close a handle for the current process */
|
||||
@ -1332,6 +1332,32 @@ struct set_serial_info_request
|
||||
#define SERIALINFO_SET_MASK 0x02
|
||||
#define SERIALINFO_SET_ERROR 0x04
|
||||
|
||||
struct create_async_request
|
||||
{
|
||||
REQUEST_HEADER; /* request header */
|
||||
IN int file_handle; /* handle to comm port */
|
||||
IN void* overlapped;
|
||||
IN void* buffer;
|
||||
IN int count;
|
||||
IN void* func;
|
||||
IN int type;
|
||||
OUT int ov_handle;
|
||||
};
|
||||
#define ASYNC_TYPE_READ 0x01
|
||||
#define ASYNC_TYPE_WRITE 0x02
|
||||
#define ASYNC_TYPE_WAIT 0x03
|
||||
|
||||
/*
|
||||
* Used by service thread to tell the server that the current
|
||||
* operation has completed
|
||||
*/
|
||||
struct async_result_request
|
||||
{
|
||||
REQUEST_HEADER; /* request header */
|
||||
IN int ov_handle;
|
||||
IN int result; /* NT status code */
|
||||
};
|
||||
|
||||
/* Everything below this line is generated automatically by tools/make_requests */
|
||||
/* ### make_requests begin ### */
|
||||
|
||||
@ -1445,6 +1471,8 @@ enum request
|
||||
REQ_CREATE_SERIAL,
|
||||
REQ_GET_SERIAL_INFO,
|
||||
REQ_SET_SERIAL_INFO,
|
||||
REQ_CREATE_ASYNC,
|
||||
REQ_ASYNC_RESULT,
|
||||
REQ_NB_REQUESTS
|
||||
};
|
||||
|
||||
@ -1560,9 +1588,11 @@ union generic_request
|
||||
struct create_serial_request create_serial;
|
||||
struct get_serial_info_request get_serial_info;
|
||||
struct set_serial_info_request set_serial_info;
|
||||
struct create_async_request create_async;
|
||||
struct async_result_request async_result;
|
||||
};
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 26
|
||||
#define SERVER_PROTOCOL_VERSION 27
|
||||
|
||||
/* ### make_requests end ### */
|
||||
/* Everything above this line is generated automatically by tools/make_requests */
|
||||
|
@ -46,6 +46,9 @@ static void call_apcs(void)
|
||||
{
|
||||
case APC_NONE:
|
||||
return; /* no more APCs */
|
||||
case APC_ASYNC:
|
||||
proc( &args[0] );
|
||||
break;
|
||||
case APC_USER:
|
||||
proc( args[0] );
|
||||
break;
|
||||
|
@ -6,6 +6,7 @@ VPATH = @srcdir@
|
||||
MODULE = none
|
||||
|
||||
C_SRCS = \
|
||||
async.c \
|
||||
atom.c \
|
||||
change.c \
|
||||
console.c \
|
||||
|
270
server/async.c
Normal file
270
server/async.c
Normal file
@ -0,0 +1,270 @@
|
||||
/*
|
||||
* Server-side support for async i/o operations
|
||||
*
|
||||
* Copyright (C) 1998 Alexandre Julliard
|
||||
* Copyright (C) 2000 Mike McCormack
|
||||
*
|
||||
* TODO:
|
||||
* Fix up WaitCommEvent operations. Currently only EV_RXCHAR is supported.
|
||||
* This may require modifications to the linux kernel to enable select
|
||||
* to wait on Modem Status Register deltas. (delta DCD, CTS, DSR or RING)
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#ifdef HAVE_SYS_ERRNO_H
|
||||
#include <sys/errno.h>
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <utime.h>
|
||||
#include <termios.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include "winerror.h"
|
||||
#include "winbase.h"
|
||||
|
||||
#include "handle.h"
|
||||
#include "thread.h"
|
||||
#include "request.h"
|
||||
|
||||
struct async
|
||||
{
|
||||
struct object obj;
|
||||
void *client_overlapped;
|
||||
int type;
|
||||
int result;
|
||||
int count;
|
||||
int eventmask;
|
||||
struct async *next;
|
||||
struct timeout_user *timeout;
|
||||
struct wait_queue_entry wait;
|
||||
void *buffer;
|
||||
void *func;
|
||||
struct thread *thread;
|
||||
struct object *file;
|
||||
};
|
||||
|
||||
static void async_dump( struct object *obj, int verbose );
|
||||
static void async_destroy( struct object *obj );
|
||||
static int async_get_poll_events( struct object *obj );
|
||||
static int async_get_read_fd( struct object *obj );
|
||||
static int async_get_write_fd( struct object *obj );
|
||||
static int async_get_info( struct object *obj, struct get_file_info_request *req );
|
||||
static void async_poll_event( struct object *obj, int event );
|
||||
|
||||
static const struct object_ops async_ops =
|
||||
{
|
||||
sizeof(struct async), /* size */
|
||||
async_dump, /* dump */
|
||||
default_poll_add_queue, /* add_queue */
|
||||
default_poll_remove_queue, /* remove_queue */
|
||||
default_poll_signaled, /* signaled */
|
||||
no_satisfied, /* satisfied */
|
||||
async_get_poll_events, /* get_poll_events */
|
||||
async_poll_event, /* poll_event */
|
||||
async_get_read_fd, /* get_read_fd */
|
||||
async_get_write_fd, /* get_write_fd */
|
||||
no_flush, /* flush */
|
||||
async_get_info, /* get_file_info */
|
||||
async_destroy /* destroy */
|
||||
};
|
||||
|
||||
static void async_dump( struct object *obj, int verbose )
|
||||
{
|
||||
struct async *ov = (struct async *)obj;
|
||||
|
||||
assert( obj->ops == &async_ops );
|
||||
|
||||
fprintf( stderr, "async: overlapped %p %s\n",
|
||||
ov->client_overlapped, ov->timeout?"with timeout":"");
|
||||
}
|
||||
|
||||
/* same as file_destroy, but don't delete comm ports */
|
||||
static void async_destroy( struct object *obj )
|
||||
{
|
||||
struct async *ov = (struct async *)obj;
|
||||
assert( obj->ops == &async_ops );
|
||||
|
||||
if(ov->timeout)
|
||||
remove_timeout_user(ov->timeout);
|
||||
ov->timeout = NULL;
|
||||
}
|
||||
|
||||
struct async *get_async_obj( struct process *process, int handle, unsigned int access )
|
||||
{
|
||||
return (struct async *)get_handle_obj( process, handle, access, &async_ops );
|
||||
}
|
||||
|
||||
static int async_get_poll_events( struct object *obj )
|
||||
{
|
||||
struct async *ov = (struct async *)obj;
|
||||
assert( obj->ops == &async_ops );
|
||||
|
||||
/* FIXME: this should be a function pointer */
|
||||
return serial_async_get_poll_events(ov);
|
||||
}
|
||||
|
||||
static int async_get_read_fd( struct object *obj )
|
||||
{
|
||||
struct async *async = (struct async *)obj;
|
||||
assert( obj->ops == &async_ops );
|
||||
return dup( async->obj.fd );
|
||||
}
|
||||
|
||||
static int async_get_write_fd( struct object *obj )
|
||||
{
|
||||
struct async *async = (struct async *)obj;
|
||||
assert( obj->ops == &async_ops );
|
||||
return dup( async->obj.fd );
|
||||
}
|
||||
|
||||
static int async_get_info( struct object *obj, struct get_file_info_request *req ) {
|
||||
assert( obj->ops == &async_ops );
|
||||
req->type = FILE_TYPE_CHAR;
|
||||
req->attr = 0;
|
||||
req->access_time = 0;
|
||||
req->write_time = 0;
|
||||
req->size_high = 0;
|
||||
req->size_low = 0;
|
||||
req->links = 0;
|
||||
req->index_high = 0;
|
||||
req->index_low = 0;
|
||||
req->serial = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* data access functions */
|
||||
int async_type(struct async *ov)
|
||||
{
|
||||
return ov->type;
|
||||
}
|
||||
|
||||
int async_count(struct async *ov)
|
||||
{
|
||||
return ov->count;
|
||||
}
|
||||
|
||||
int async_get_eventmask(struct async *ov)
|
||||
{
|
||||
return ov->eventmask;
|
||||
}
|
||||
|
||||
int async_set_eventmask(struct async *ov, int eventmask)
|
||||
{
|
||||
return ov->eventmask = eventmask;
|
||||
}
|
||||
|
||||
DECL_HANDLER(create_async)
|
||||
{
|
||||
struct object *obj;
|
||||
struct async *ov = NULL;
|
||||
int fd;
|
||||
|
||||
req->ov_handle = -1;
|
||||
if (!(obj = get_handle_obj( current->process, req->file_handle, 0, NULL)) )
|
||||
return;
|
||||
|
||||
fd = dup(obj->fd);
|
||||
if(fd<0)
|
||||
{
|
||||
release_object(obj);
|
||||
set_error(STATUS_UNSUCCESSFUL);
|
||||
return;
|
||||
}
|
||||
|
||||
if(0>fcntl(fd, F_SETFL, O_NONBLOCK))
|
||||
{
|
||||
release_object(obj);
|
||||
set_error(STATUS_UNSUCCESSFUL);
|
||||
return;
|
||||
}
|
||||
|
||||
ov = alloc_object (&async_ops, fd);
|
||||
if(!ov)
|
||||
{
|
||||
release_object(obj);
|
||||
set_error(STATUS_UNSUCCESSFUL);
|
||||
return;
|
||||
}
|
||||
|
||||
ov->client_overlapped = req->overlapped;
|
||||
ov->next = NULL;
|
||||
ov->timeout = NULL;
|
||||
ov->type = req->type;
|
||||
ov->thread = current;
|
||||
ov->func = req->func;
|
||||
ov->file = obj;
|
||||
ov->buffer = req->buffer;
|
||||
ov->count = req->count;
|
||||
|
||||
/* FIXME: this should be a function pointer */
|
||||
serial_async_setup(obj,ov);
|
||||
|
||||
ov->obj.ops->add_queue(&ov->obj,&ov->wait);
|
||||
|
||||
req->ov_handle = alloc_handle( current->process, ov, GENERIC_READ|GENERIC_WRITE, 0 );
|
||||
|
||||
release_object(obj);
|
||||
}
|
||||
|
||||
/* handler for async poll() events */
|
||||
static void async_poll_event( struct object *obj, int event )
|
||||
{
|
||||
struct async *ov = (struct async *) obj;
|
||||
|
||||
/* queue an APC in the client thread to do our dirty work */
|
||||
ov->obj.ops->remove_queue(&ov->obj,&ov->wait);
|
||||
|
||||
/* FIXME: this should be a function pointer */
|
||||
event = serial_async_poll_event(obj,event);
|
||||
|
||||
thread_queue_apc(ov->thread, NULL, ov->func, APC_ASYNC, 3,
|
||||
ov->client_overlapped, ov->buffer, event);
|
||||
}
|
||||
|
||||
/* handler for async i/o timeouts */
|
||||
static void overlapped_timeout (void *private)
|
||||
{
|
||||
struct async *ov = (struct async *) private;
|
||||
|
||||
ov->obj.ops->remove_queue(&ov->obj,&ov->wait);
|
||||
|
||||
thread_queue_apc(ov->thread, NULL, ov->func, APC_ASYNC, 3,
|
||||
ov->client_overlapped,ov->buffer, 0);
|
||||
}
|
||||
|
||||
void async_add_timeout(struct async *ov, int timeout)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv,0);
|
||||
add_timeout(&tv,timeout);
|
||||
ov->timeout = add_timeout_user(&tv, overlapped_timeout, ov);
|
||||
}
|
||||
|
||||
DECL_HANDLER(async_result)
|
||||
{
|
||||
struct async *ov;
|
||||
|
||||
if ((ov = get_async_obj( current->process, req->ov_handle, 0 )))
|
||||
{
|
||||
ov->result = req->result;
|
||||
if(ov->result == STATUS_PENDING)
|
||||
{
|
||||
ov->obj.ops->add_queue(&ov->obj,&ov->wait);
|
||||
}
|
||||
release_object( ov );
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ struct thread;
|
||||
struct process;
|
||||
struct file;
|
||||
struct wait_queue_entry;
|
||||
struct async;
|
||||
|
||||
/* operations valid on all objects */
|
||||
struct object_ops
|
||||
@ -156,6 +157,20 @@ extern int create_anonymous_file(void);
|
||||
extern struct file *create_temp_file( int access );
|
||||
extern void file_set_error(void);
|
||||
|
||||
/* async functions */
|
||||
|
||||
void async_add_timeout(struct async *ov, int timeout);
|
||||
int async_count(struct async *ov);
|
||||
int async_type(struct async *ov);
|
||||
int async_get_eventmask(struct async *ov);
|
||||
int async_set_eventmask(struct async *ov, int eventmask);
|
||||
|
||||
/* serial functions */
|
||||
|
||||
int serial_async_setup(struct object *obj, struct async *ov);
|
||||
int serial_async_get_poll_events( struct async *ov );
|
||||
int serial_async_poll_event(struct object *obj, int event);
|
||||
|
||||
/* console functions */
|
||||
|
||||
extern int alloc_console( struct process *process );
|
||||
|
@ -202,6 +202,8 @@ DECL_HANDLER(wait_input_idle);
|
||||
DECL_HANDLER(create_serial);
|
||||
DECL_HANDLER(get_serial_info);
|
||||
DECL_HANDLER(set_serial_info);
|
||||
DECL_HANDLER(create_async);
|
||||
DECL_HANDLER(async_result);
|
||||
|
||||
#ifdef WANT_REQUEST_HANDLERS
|
||||
|
||||
@ -316,6 +318,8 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
|
||||
(req_handler)req_create_serial,
|
||||
(req_handler)req_get_serial_info,
|
||||
(req_handler)req_set_serial_info,
|
||||
(req_handler)req_create_async,
|
||||
(req_handler)req_async_result,
|
||||
};
|
||||
#endif /* WANT_REQUEST_HANDLERS */
|
||||
|
||||
|
@ -182,6 +182,77 @@ static int serial_get_info( struct object *obj, struct get_file_info_request *re
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* these functions are for interaction with asynchronous i/o objects */
|
||||
int serial_async_setup(struct object *obj, struct async *ov)
|
||||
{
|
||||
struct serial *serial = (struct serial *)obj;
|
||||
int timeout;
|
||||
|
||||
if(obj->ops != &serial_ops)
|
||||
return 0;
|
||||
|
||||
switch(async_type(ov))
|
||||
{
|
||||
case ASYNC_TYPE_READ:
|
||||
timeout = serial->readconst + serial->readmult*async_count(ov);
|
||||
async_add_timeout(ov, timeout);
|
||||
async_set_eventmask(ov,EV_RXCHAR);
|
||||
break;
|
||||
case ASYNC_TYPE_WRITE:
|
||||
timeout = serial->writeconst + serial->writemult*async_count(ov);
|
||||
async_add_timeout(ov, timeout);
|
||||
async_set_eventmask(ov,EV_TXEMPTY);
|
||||
break;
|
||||
case ASYNC_TYPE_WAIT:
|
||||
async_set_eventmask(ov,serial->eventmask);
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int serial_async_get_poll_events( struct async *ov )
|
||||
{
|
||||
int events=0,mask;
|
||||
|
||||
switch(async_type(ov))
|
||||
{
|
||||
case ASYNC_TYPE_READ:
|
||||
events |= POLLIN;
|
||||
break;
|
||||
case ASYNC_TYPE_WRITE:
|
||||
events |= POLLOUT;
|
||||
break;
|
||||
case ASYNC_TYPE_WAIT:
|
||||
/*
|
||||
* FIXME: here is the spot to implement other WaitCommEvent flags
|
||||
*/
|
||||
mask = async_get_eventmask(ov);
|
||||
if(mask&EV_RXCHAR)
|
||||
events |= POLLIN;
|
||||
if(mask&EV_TXEMPTY)
|
||||
events |= POLLOUT;
|
||||
break;
|
||||
}
|
||||
return events;
|
||||
}
|
||||
|
||||
/* receive a select event, and output a windows event */
|
||||
int serial_async_poll_event(struct object *obj, int event)
|
||||
{
|
||||
int r=0;
|
||||
|
||||
/*
|
||||
* FIXME: here is the spot to implement other WaitCommEvent flags
|
||||
*/
|
||||
if(event & POLLIN)
|
||||
r |= EV_RXCHAR;
|
||||
if(event & POLLOUT)
|
||||
r |= EV_TXEMPTY;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* create a serial */
|
||||
DECL_HANDLER(create_serial)
|
||||
{
|
||||
|
@ -1455,6 +1455,27 @@ static void dump_set_serial_info_request( const struct set_serial_info_request *
|
||||
fprintf( stderr, " commerror=%08x", req->commerror );
|
||||
}
|
||||
|
||||
static void dump_create_async_request( const struct create_async_request *req )
|
||||
{
|
||||
fprintf( stderr, " file_handle=%d,", req->file_handle );
|
||||
fprintf( stderr, " overlapped=%p,", req->overlapped );
|
||||
fprintf( stderr, " buffer=%p,", req->buffer );
|
||||
fprintf( stderr, " count=%d,", req->count );
|
||||
fprintf( stderr, " func=%p,", req->func );
|
||||
fprintf( stderr, " type=%d", req->type );
|
||||
}
|
||||
|
||||
static void dump_create_async_reply( const struct create_async_request *req )
|
||||
{
|
||||
fprintf( stderr, " ov_handle=%d", req->ov_handle );
|
||||
}
|
||||
|
||||
static void dump_async_result_request( const struct async_result_request *req )
|
||||
{
|
||||
fprintf( stderr, " ov_handle=%d,", req->ov_handle );
|
||||
fprintf( stderr, " result=%d", req->result );
|
||||
}
|
||||
|
||||
static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
||||
(dump_func)dump_new_process_request,
|
||||
(dump_func)dump_wait_process_request,
|
||||
@ -1564,6 +1585,8 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
||||
(dump_func)dump_create_serial_request,
|
||||
(dump_func)dump_get_serial_info_request,
|
||||
(dump_func)dump_set_serial_info_request,
|
||||
(dump_func)dump_create_async_request,
|
||||
(dump_func)dump_async_result_request,
|
||||
};
|
||||
|
||||
static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
||||
@ -1675,6 +1698,8 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
||||
(dump_func)dump_create_serial_reply,
|
||||
(dump_func)dump_get_serial_info_reply,
|
||||
(dump_func)0,
|
||||
(dump_func)dump_create_async_reply,
|
||||
(dump_func)0,
|
||||
};
|
||||
|
||||
static const char * const req_names[REQ_NB_REQUESTS] = {
|
||||
@ -1786,6 +1811,8 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
|
||||
"create_serial",
|
||||
"get_serial_info",
|
||||
"set_serial_info",
|
||||
"create_async",
|
||||
"async_result",
|
||||
};
|
||||
|
||||
/* ### make_requests end ### */
|
||||
|
Loading…
x
Reference in New Issue
Block a user