1645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Copyright 2014 The Chromium Authors. All rights reserved. 2645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Use of this source code is governed by a BSD-style license that can be 3645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// found in the LICENSE file. 4645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 5645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#ifdef __cplusplus 6645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#error "This file should be compiled as C, not C++." 7645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#endif 8645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 9645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <stddef.h> 10645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <stdint.h> 11645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <string.h> 12645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 13645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Include all the header files that are meant to be compilable as C. Start with 14645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// core.h, since it's the most important one. 15645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/public/c/system/core.h" 16645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/public/c/system/macros.h" 17645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 18645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// The joys of the C preprocessor.... 19645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#define STRINGIFY(x) #x 20645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#define STRINGIFY2(x) STRINGIFY(x) 21645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#define FAILURE(message) \ 22645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez __FILE__ "(" STRINGIFY2(__LINE__) "): Failure: " message 23645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 24645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Poor man's gtest. 25645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#define EXPECT_EQ(a, b) \ 26645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez do { \ 27645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez if ((a) != (b)) \ 28645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return FAILURE(STRINGIFY(a) " != " STRINGIFY(b) " (expected ==)"); \ 29645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez } while (0) 30645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#define EXPECT_NE(a, b) \ 31645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez do { \ 32645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez if ((a) == (b)) \ 33645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return FAILURE(STRINGIFY(a) " == " STRINGIFY(b) " (expected !=)"); \ 34645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez } while (0) 35645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 36645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// This function exists mainly to be compiled and linked. We do some cursory 37645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// checks and call it from a unit test, to make sure that link problems aren't 38645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// missed due to deadstripping. Returns null on success and a string on failure 39645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// (describing the failure). 40645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezconst char* MinimalCTest(void) { 41645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // MSVS before 2013 *really* only supports C90: All variables must be declared 42645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // at the top. (MSVS 2013 is more reasonable.) 43645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez MojoTimeTicks ticks; 44645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez MojoHandle handle0, handle1; 45645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez MojoHandleSignals signals; 46645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez const char kHello[] = "hello"; 47645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez char buffer[200] = {0}; 48645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez uint32_t num_bytes; 49645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 50645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez ticks = MojoGetTimeTicksNow(); 51645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez EXPECT_NE(ticks, 0); 52645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 53645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez handle0 = MOJO_HANDLE_INVALID; 54645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez EXPECT_NE(MOJO_RESULT_OK, MojoClose(handle0)); 55645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 56645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, 57645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez MojoWait(handle0, ~MOJO_HANDLE_SIGNAL_NONE, 58645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez MOJO_DEADLINE_INDEFINITE, NULL)); 59645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 60645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez handle1 = MOJO_HANDLE_INVALID; 61645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez EXPECT_EQ(MOJO_RESULT_OK, MojoCreateMessagePipe(NULL, &handle0, &handle1)); 62645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 63645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez signals = MOJO_HANDLE_SIGNAL_READABLE; 64645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez uint32_t result_index = 123; 65645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez struct MojoHandleSignalsState states[1]; 66645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, 67645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez MojoWaitMany(&handle0, &signals, 1, 1, &result_index, states)); 68645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 69645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // "Deadline exceeded" doesn't apply to a single handle, so this should leave 70645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // |result_index| untouched. 71645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez EXPECT_EQ(123u, result_index); 72645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, states[0].satisfied_signals); 73645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE | 74645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez MOJO_HANDLE_SIGNAL_PEER_CLOSED, 75645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez states[0].satisfiable_signals); 76645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 77645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez EXPECT_EQ(MOJO_RESULT_OK, 78645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez MojoWriteMessage(handle0, kHello, (uint32_t)sizeof(kHello), NULL, 79645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 0u, MOJO_WRITE_DATA_FLAG_NONE)); 80645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 81645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez struct MojoHandleSignalsState state; 82645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez EXPECT_EQ(MOJO_RESULT_OK, MojoWait(handle1, MOJO_HANDLE_SIGNAL_READABLE, 83645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez MOJO_DEADLINE_INDEFINITE, &state)); 84645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 85645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 86645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez state.satisfied_signals); 87645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE | 88645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez MOJO_HANDLE_SIGNAL_PEER_CLOSED, 89645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez state.satisfiable_signals); 90645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 91645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez num_bytes = (uint32_t)sizeof(buffer); 92645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez EXPECT_EQ(MOJO_RESULT_OK, MojoReadMessage(handle1, buffer, &num_bytes, NULL, 93645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez NULL, MOJO_READ_MESSAGE_FLAG_NONE)); 94645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez EXPECT_EQ((uint32_t)sizeof(kHello), num_bytes); 95645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez EXPECT_EQ(0, memcmp(buffer, kHello, sizeof(kHello))); 96645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 97645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez EXPECT_EQ(MOJO_RESULT_OK, MojoClose(handle0)); 98645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez EXPECT_EQ(MOJO_RESULT_OK, MojoClose(handle1)); 99645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 100645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // TODO(vtl): data pipe 101645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 102645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return NULL; 103645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez} 104