diff --git a/libc/Android.mk b/libc/Android.mk index c47cc6722..3c387d2e1 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -238,7 +238,8 @@ libc_bionic_src_files := \ bionic/brk.cpp \ bionic/dirent.cpp \ bionic/__errno.c \ - bionic/eventfd.cpp \ + bionic/eventfd_read.cpp \ + bionic/eventfd_write.cpp \ bionic/__fgets_chk.cpp \ bionic/getauxval.cpp \ bionic/getcwd.cpp \ diff --git a/libc/bionic/eventfd.cpp b/libc/bionic/eventfd_read.cpp similarity index 75% rename from libc/bionic/eventfd.cpp rename to libc/bionic/eventfd_read.cpp index fc7a6b9b6..50e73fd54 100644 --- a/libc/bionic/eventfd.cpp +++ b/libc/bionic/eventfd_read.cpp @@ -29,25 +29,6 @@ #include #include -/* We duplicate the GLibc error semantics, which are poorly defined - * if the read() or write() does not return the proper number of bytes. - */ -int eventfd_read(int fd, eventfd_t *counter) -{ - int ret = read(fd, counter, sizeof(*counter)); - - if (ret == sizeof(*counter)) - return 0; - - return -1; -} - -int eventfd_write(int fd, eventfd_t counter) -{ - int ret = write(fd, &counter, sizeof(counter)); - - if (ret == sizeof(counter)) - return 0; - - return -1; +int eventfd_read(int fd, eventfd_t* value) { + return (read(fd, value, sizeof(*value)) == sizeof(*value)) ? 0 : -1; } diff --git a/libc/bionic/eventfd_write.cpp b/libc/bionic/eventfd_write.cpp new file mode 100644 index 000000000..3c3d3f1cc --- /dev/null +++ b/libc/bionic/eventfd_write.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +int eventfd_write(int fd, eventfd_t value) { + return (write(fd, &value, sizeof(value)) == sizeof(value)) ? 0 : -1; +} diff --git a/libc/include/sys/eventfd.h b/libc/include/sys/eventfd.h index 19244a5d7..ec84e27b7 100644 --- a/libc/include/sys/eventfd.h +++ b/libc/include/sys/eventfd.h @@ -33,17 +33,16 @@ __BEGIN_DECLS -#define EFD_CLOEXEC O_CLOEXEC -#define EFD_NONBLOCK O_NONBLOCK +#define EFD_CLOEXEC O_CLOEXEC +#define EFD_NONBLOCK O_NONBLOCK /* type of event counter */ -typedef uint64_t eventfd_t; +typedef uint64_t eventfd_t; -extern int eventfd(unsigned int initval, int flags); +extern int eventfd(unsigned int initial_value, int flags); -/* Compatibility with GLibc */ -extern int eventfd_read(int fd, eventfd_t *counter); -extern int eventfd_write(int fd, const eventfd_t counter); +extern int eventfd_read(int fd, eventfd_t* value); +extern int eventfd_write(int fd, eventfd_t value); __END_DECLS diff --git a/tests/Android.mk b/tests/Android.mk index 491b13c15..dee5e3311 100644 --- a/tests/Android.mk +++ b/tests/Android.mk @@ -58,6 +58,7 @@ test_c_flags = \ test_src_files = \ dirent_test.cpp \ + eventfd_test.cpp \ fenv_test.cpp \ getauxval_test.cpp \ getcwd_test.cpp \ diff --git a/tests/eventfd_test.cpp b/tests/eventfd_test.cpp new file mode 100644 index 000000000..2c2c5f07e --- /dev/null +++ b/tests/eventfd_test.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#if !defined(__GLIBC__) // Android's prebuilt gcc's header files don't include . + +#include + +TEST(eventfd, smoke) { + unsigned int initial_value = 2; + int fd = eventfd(initial_value, O_NONBLOCK); + ASSERT_NE(fd, -1); + + eventfd_t value = 123; + ASSERT_EQ(0, eventfd_read(fd, &value)); + ASSERT_EQ(initial_value, value); + + // Reading clears the counter. + ASSERT_EQ(-1, eventfd_read(fd, &value)); + ASSERT_EQ(EAGAIN, errno); + + // Values written are added until the next read. + ASSERT_EQ(0, eventfd_write(fd, 1)); + ASSERT_EQ(0, eventfd_write(fd, 1)); + ASSERT_EQ(0, eventfd_write(fd, 1)); + + ASSERT_EQ(0, eventfd_read(fd, &value)); + ASSERT_EQ(3U, value); + + close(fd); +} + +#endif