From 84adefa331c4159d432d22840663c38f155cd4c1 Mon Sep 17 00:00:00 2001 From: Erlang/OTP Date: Fri, 20 Nov 2009 14:54:40 +0000 Subject: The R13B03 release. --- .../peek_non_existing_queue_drv.c | 231 +++++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 erts/emulator/test/driver_SUITE_data/peek_non_existing_queue_drv.c (limited to 'erts/emulator/test/driver_SUITE_data/peek_non_existing_queue_drv.c') diff --git a/erts/emulator/test/driver_SUITE_data/peek_non_existing_queue_drv.c b/erts/emulator/test/driver_SUITE_data/peek_non_existing_queue_drv.c new file mode 100644 index 0000000000..f429a5b51e --- /dev/null +++ b/erts/emulator/test/driver_SUITE_data/peek_non_existing_queue_drv.c @@ -0,0 +1,231 @@ +/* ``The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved via the world wide web at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * The Initial Developer of the Original Code is Ericsson Utvecklings AB. + * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings + * AB. All Rights Reserved.'' + * + * $Id$ + */ + +/* + * Author: Rickard Green + * + * Description: Tests that port I/O queues can be flushed via: + * - ready_input(), + * - ready_output(), + * - timeout(), + * - driver_async() -> read_async(), and + * - event() + */ + +#ifndef UNIX +#if !defined(__WIN32__) && !defined(_OSE_) && !defined(VXWORKS) +#define UNIX 1 +#endif +#endif + +#if defined(DEBUG) || 0 +# define PRINTF(X) printf X +#else +# define PRINTF(X) +#endif + +#if defined(UNIX) +#include +#include +#elif defined(__WIN32__) +#include +#endif + +#include + +#include "erl_driver.h" + +#define PEEK_NONXQ_TEST 0 +#define PEEK_NONXQ_WAIT 1 + +typedef struct { + ErlDrvTermData caller; + ErlDrvPort port; + int cmd; +} PeekNonXQDrvData; + +typedef struct { + ErlDrvPort port; + ErlDrvPDL pdl; +} AsyncData; + +static ErlDrvData start(ErlDrvPort, char *); +static void stop(ErlDrvData); +static int control(ErlDrvData, unsigned int, char *, int, char **, int); +static void ready_async(ErlDrvData, ErlDrvThreadData); +static void async_test(void *); +static void async_wait(void *); +static void async_free(void *); +static void do_sleep(unsigned); + +static ErlDrvEntry peek_non_existing_queue_drv_entry = { + NULL /* init */, + start, + stop, + NULL /* output */, + NULL /* ready_input */, + NULL /* ready_output */, + "peek_non_existing_queue_drv", + NULL /* finish */, + NULL /* handle */, + control, + NULL /* timeout */, + NULL /* outputv */, + ready_async, + NULL /* flush */, + NULL /* call */, + NULL /* event */, + ERL_DRV_EXTENDED_MARKER, + ERL_DRV_EXTENDED_MAJOR_VERSION, + ERL_DRV_EXTENDED_MINOR_VERSION, + ERL_DRV_FLAG_USE_PORT_LOCKING, + NULL /* handle2 */, + NULL /* process_exit */ +}; + +DRIVER_INIT(peek_non_existing_queue_drv) +{ + return &peek_non_existing_queue_drv_entry; +} + +static ErlDrvData +start(ErlDrvPort port, char *command) +{ + PeekNonXQDrvData *dp = driver_alloc(sizeof(PeekNonXQDrvData)); + if (!dp) { + errno = ENOMEM; + return ERL_DRV_ERROR_ERRNO; + } + + dp->port = port; + return (ErlDrvData) dp; +} + +static void stop(ErlDrvData drv_data) +{ + driver_free(drv_data); +} + +static int control(ErlDrvData drv_data, + unsigned int command, + char *buf, int len, + char **rbuf, int rlen) +{ + PeekNonXQDrvData *dp = (PeekNonXQDrvData *) drv_data; + unsigned int key = 0; + char *res_str = "ok"; + ErlDrvSysInfo si; + driver_system_info(&si, sizeof(ErlDrvSysInfo)); + if (si.async_threads == 0) { + res_str = "skipped: No async-threads available"; + goto done; + } + + dp->cmd = command; + dp->caller = driver_caller(dp->port); + + switch (command) { + case PEEK_NONXQ_TEST: { + AsyncData *adp = driver_alloc(sizeof(AsyncData)); + if (!adp) { + res_str = "enomem"; + goto done; + } + driver_enq(dp->port, "!", 1); + adp->port = dp->port; + adp->pdl = driver_pdl_create(dp->port); + (void) driver_async(dp->port, &key, async_test, adp, async_free); + break; + } + case PEEK_NONXQ_WAIT: + (void) driver_async(dp->port, &key, async_wait, NULL, NULL); + break; + } + + done: { + int res_len = strlen(res_str); + if (res_len > rlen) { + char *abuf = driver_alloc(sizeof(char)*res_len); + if (!abuf) + return 0; + *rbuf = abuf; + } + + memcpy((void *) *rbuf, (void *) res_str, res_len); + + return res_len; + } +} + +static void ready_async(ErlDrvData drv_data, ErlDrvThreadData thread_data) +{ + PeekNonXQDrvData *dp = (PeekNonXQDrvData *) drv_data; + if (dp->cmd == PEEK_NONXQ_WAIT) { + ErlDrvTermData spec[] = { + ERL_DRV_PORT, driver_mk_port(dp->port), + ERL_DRV_ATOM, driver_mk_atom("test_successful"), + ERL_DRV_TUPLE, 2 + }; + driver_send_term(dp->port, + dp->caller, + spec, + sizeof(spec) / sizeof(spec[0])); + } + if (thread_data) + driver_free(thread_data); +} + +static void async_test(void *vadp) +{ + SysIOVec *vec; + int vlen = 4711; + AsyncData *adp = (AsyncData *)vadp; + + do_sleep(1); + + driver_pdl_lock(adp->pdl); + vec = driver_peekq(adp->port, &vlen); + if (vlen >= 0 || vec) + abort(); /* A crude way to fail the test, but what the ... */ + vlen = driver_sizeq(adp->port); + if (vlen >= 0) + abort(); /* ... */ + driver_pdl_unlock(adp->pdl); +} + +static void async_wait(void *vadp) +{ + /* Will always be executed after async_test in the same thread */ +} + + +static void async_free(void *vadp) +{ + driver_free(vadp); +} + +static void +do_sleep(unsigned secs) +{ +#ifdef __WIN32__ + Sleep((DWORD) secs*1000); +#else + sleep(secs); +#endif +} + -- cgit v1.2.3