lwan-coro.h 2.64 KB
Newer Older
Bryton Lacquement's avatar
Bryton Lacquement committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
/*
 * lwan - simple web server
 * Copyright (c) 2012 Leandro A. F. Pereira <leandro@hardinfo.org>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#pragma once

#if defined (__cplusplus)
extern "C" {
#endif

#include <stddef.h>
#if defined(__x86_64__)
#include <stdint.h>
typedef uintptr_t coro_context[10];
#elif defined(__i386__)
#include <stdint.h>
typedef uintptr_t coro_context[7];
#else
#include <ucontext.h>
typedef ucontext_t coro_context;
#endif

#define DEFAULT_BUFFER_SIZE 4096
#define ALWAYS_INLINE inline __attribute__((always_inline))

struct coro;
typedef struct coro coro_t;

typedef int    (*coro_function_t)	(struct coro *coro, void *data);

typedef struct coro_switcher {
    coro_context caller;
    coro_context callee;
}coro_switcher_t;

struct coro *coro_new(struct coro_switcher *switcher, coro_function_t function, void *data);
void	coro_free(struct coro *coro);

void    coro_reset(struct coro *coro, coro_function_t func, void *data);
void    coro_update(struct coro *coro, struct coro_switcher *new_switcher);

int	coro_resume(struct coro *coro);
int	coro_resume_value(struct coro *coro, int value);
int	coro_yield(struct coro *coro, int value);

void    coro_defer(struct coro *coro, void (*func)(void *data), void *data);
void    coro_defer2(struct coro *coro, void (*func)(void *data1, void *data2),
            void *data1, void *data2);

void    coro_deferred_run(struct coro *coro, size_t generation);
size_t  coro_deferred_get_generation(const struct coro *coro);

void   *coro_malloc(struct coro *coro, size_t sz)
            __attribute__((malloc));
void   *coro_malloc_full(struct coro *coro, size_t size, void (*destroy_func)())
            __attribute__((malloc));
char   *coro_strdup(struct coro *coro, const char *str);
char   *coro_strndup(struct coro *coro, const char *str, size_t len);
char   *coro_printf(struct coro *coro, const char *fmt, ...);

#define CORO_DEFER(fn)		((void (*)(void *))(fn))
#define CORO_DEFER2(fn)		((void (*)(void *, void *))(fn))

#if defined (__cplusplus)
}
#endif