+++ /dev/null
-/* Copyright (c) 2010, 2012-2014. The SimGrid Team.
- * All rights reserved. */
-
-/* This program is free software; you can redistribute it and/or modify it
- * under the terms of the license (GNU LGPL) which comes with this package. */
-
-#include "lua_private.h"
-#include <lauxlib.h>
-
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(lua_comm, bindings, "Lua bindings (comm module)");
-
-#define COMM_MODULE_NAME "simgrid.comm"
-
-/* ********************************************************************************* */
-/* simgrid.comm API */
-/* ********************************************************************************* */
-
-/**
- * \brief Ensures that a value in the stack is a comm and returns it.
- * \param L a Lua state
- * \param index an index in the Lua stack
- * \return the C comm
- */
-msg_comm_t sglua_check_comm(lua_State* L, int index)
-{
- msg_comm_t comm = *((msg_comm_t*) luaL_checkudata(L, index, COMM_MODULE_NAME));
- return comm;
-}
-
-/**
- * \brief Pushes a comm onto the stack.
- * \param L a Lua state
- * \param comm a comm
- */
-void sglua_push_comm(lua_State* L, msg_comm_t comm)
-{
- msg_comm_t* userdata = (msg_comm_t*) lua_newuserdata(L, sizeof(msg_comm_t));
- /* comm */
- *userdata = comm;
- luaL_getmetatable(L, COMM_MODULE_NAME);
- /* comm mt */
- lua_setmetatable(L, -2);
- /* comm */
-}
-
-/**
- * \brief Blocks the current process until a communication is finished.
- * \param L a Lua state
- * \return number of values returned to Lua
- *
- * - Argument 1 (comm): a comm (previously created by isend or irecv)
- * - Argument 2 (number, optional): timeout (default is no timeout)
- * - Return values (task or nil + string): in case of success, returns the task
- * received if you are the receiver and nil if you are the sender. In case of
- * failure, returns nil plus an error string.
- */
-static int l_comm_wait(lua_State* L) {
-
- msg_comm_t comm = sglua_check_comm(L, 1);
- double timeout = -1;
- if (lua_gettop(L) >= 2) {
- timeout = luaL_checknumber(L, 2);
- }
- /* comm ... */
- msg_error_t res = MSG_comm_wait(comm, timeout);
-
- if (res == MSG_OK) {
- msg_task_t task = MSG_comm_get_task(comm);
- if (MSG_task_get_sender(task) == MSG_process_self()) {
- /* I'm the sender */
- return 0;
- }
- else {
- /* I'm the receiver: find the Lua task from the C task */
- sglua_task_unregister(L, task);
- /* comm ... task */
- return 1;
- }
- }
- else {
- /* the communication has failed */
- lua_pushnil(L);
- /* comm ... nil */
- lua_pushstring(L, sglua_get_msg_error(res));
- /* comm ... nil error */
- return 2;
- }
-}
-
-/**
- * @brief Returns whether a communication is finished.
- *
- * Unlike wait(), This function always returns immediately.
- *
- * - Argument 1 (comm): a comm (previously created by isend or irecv)
- * - Return values (task/boolean or nil + string): if the communication is not
- * finished, return false. If the communication is finished and was successful,
- * returns the task received if you are the receiver or true if you are the
- * sender. If the communication is finished and has failed, returns nil
- * plus an error string.
- */
-static int l_comm_test(lua_State* L) {
-
- msg_comm_t comm = sglua_check_comm(L, 1);
- /* comm ... */
- if (!MSG_comm_test(comm)) {
- /* not finished yet */
- lua_pushboolean(L, 0);
- /* comm ... false */
- return 1;
- }
- else {
- /* finished but may have failed */
- msg_error_t res = MSG_comm_get_status(comm);
-
- if (res == MSG_OK) {
- msg_task_t task = MSG_comm_get_task(comm);
- if (MSG_task_get_sender(task) == MSG_process_self()) {
- /* I'm the sender */
- lua_pushboolean(L, 1);
- /* comm ... true */
- return 1;
- }
- else {
- /* I'm the receiver: find the Lua task from the C task*/
- sglua_task_unregister(L, task);
- /* comm ... task */
- return 1;
- }
- }
- else {
- /* the communication has failed */
- lua_pushnil(L);
- /* comm ... nil */
- lua_pushstring(L, sglua_get_msg_error(res));
- /* comm ... nil error */
- return 2;
- }
- }
-}
-
-static const luaL_Reg comm_functions[] = {
- {"wait", l_comm_wait},
- {"test", l_comm_test},
- /* TODO waitany, testany */
- {NULL, NULL}
-};
-
-/**
- * \brief Finalizes a comm userdata.
- * \param L a Lua state
- * \return number of values returned to Lua
- *
- * - Argument 1 (userdata): a comm
- */
-static int l_comm_gc(lua_State* L)
-{
- /* ctask */
- msg_comm_t comm = *((msg_comm_t*) luaL_checkudata(L, 1, COMM_MODULE_NAME));
- MSG_comm_destroy(comm);
- return 0;
-}
-
-/**
- * \brief Metamethods of the comm userdata.
- */
-static const luaL_Reg comm_meta[] = {
- {"__gc", l_comm_gc},
- {NULL, NULL}
-};
-
-/**
- * \brief Registers the comm functions into the table simgrid.comm.
- *
- * Also initialize the metatable of the comm userdata type.
- *
- * \param L a lua state
- */
-void sglua_register_comm_functions(lua_State* L)
-{
- /* create a table simgrid.comm and fill it with com functions */
- lua_getglobal(L, "simgrid"); /* simgrid */
- luaL_newlib(L, comm_functions); /* simgrid simgrid.comm */
-
- /* create the metatable for comm, add it to the Lua registry */
- luaL_newmetatable(L, COMM_MODULE_NAME); /* simgrid simgrid.comm mt */
-
- /* fill the metatable */
- luaL_setfuncs(L, comm_meta, 0); /* simgrid simgrid.comm mt */
-
- /**
- * Copy the table and push it onto the stack.
- * Required for the lua_setfield call below.
- */
- lua_pushvalue(L, -2); /* simgrid simgrid.comm mt simgrid.comm */
-
- /* metatable.__index = simgrid.comm
- * we put the comm functions inside the comm userdata itself:
- * this allows to write my_comm:method(args) for
- * simgrid.comm.method(my_comm, args) */
- lua_setfield(L, -2, "__index"); /* simgrid simgrid.comm mt */
-
- lua_setmetatable(L, -2); /* simgrid simgrid.comm */
- lua_setfield(L, -1, "comm"); /* simgrid */
- lua_pop(L, 1); /* -- */
-}
-