Exemplo n.º 1
0
static ERL_NIF_TERM
_listener (ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
  CAN_handle* handle;
  ErlNifPid pid = { 0 }; // NOTE: breaking opaque type!
  enif_get_resource(env, argv[0], CAN_handle_type, (void**) &handle);
  if (handle->threaded) // there is a thread already and some pid!
  {
    pid = handle->receiver;
  }
  if (!enif_get_local_pid(env, argv[1], &handle->receiver)) // NOTE: use lock if pid type is structural!
    {
      handle->threaded = 0;
      return enif_make_badarg(env);
    }
  else
    {
      enif_get_uint(env, argv[2], &handle->chunk_size);
      enif_get_long(env, argv[3], &handle->timeout);
      if (!handle->threaded) // a thread was not created already
        {
          if (enif_thread_create("can_reading_thread",
              &handle->tid,
              _reading_thread,
              handle, 0))
            {
              handle->threaded = 0;
              return enif_make_int(env, -1004);
            }
        }
    }
  return pid.pid ? enif_make_pid(env, &pid) : enif_make_int(env, 0);
}
Exemplo n.º 2
0
static ERL_NIF_TERM send_from_dirty_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    ERL_NIF_TERM result;
    ErlNifPid pid;
    int res;

    if (!enif_get_local_pid(env, argv[0], &pid))
	return enif_make_badarg(env);
    result = enif_make_tuple2(env, enif_make_atom(env, "ok"), enif_make_pid(env, &pid));
    res = enif_send(env, &pid, NULL, result);
    if (!res)
	return enif_make_badarg(env);
    else
	return result;
}
Exemplo n.º 3
0
static int whereis_lookup_term(
    ErlNifEnv* env, int type, ERL_NIF_TERM name, ERL_NIF_TERM* out)
{
    whereis_term_data_t res;
    int rc = whereis_lookup_internal(env, type, name, &res);
    if (rc == WHEREIS_SUCCESS) {
        switch (type) {
            case WHEREIS_LOOKUP_PID:
                *out = enif_make_pid(env, & res.pid);
                break;
            case WHEREIS_LOOKUP_PORT:
                *out = enif_make_port(env, & res.port);
                break;
            default:
                rc = WHEREIS_ERROR_TYPE;
                break;
        }
    }
    return rc;
}
Exemplo n.º 4
0
static ERL_NIF_TERM dirty_call_while_terminated_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    ErlNifPid self;
    ERL_NIF_TERM result, self_term;
    ErlNifPid to;
    ErlNifEnv* menv;
    int res;

    if (!enif_get_local_pid(env, argv[0], &to))
	return enif_make_badarg(env);

    if (!enif_self(env, &self))
	return enif_make_badarg(env);

    self_term = enif_make_pid(env, &self);

    menv = enif_alloc_env();
    result = enif_make_tuple2(menv, enif_make_atom(menv, "dirty_alive"), self_term);
    res = enif_send(env, &to, menv, result);
    enif_free_env(menv);
    if (!res)
	return enif_make_badarg(env);

    /* Wait until we have been killed */
    while (enif_is_process_alive(env, &self))
	;

    result = enif_make_tuple2(env, enif_make_atom(env, "dirty_dead"), self_term);
    res = enif_send(env, &to, NULL, result);

#ifdef __WIN32__
    Sleep(1000);
#else
    sleep(1);
#endif

    return enif_make_atom(env, "ok");
}
Exemplo n.º 5
0
static ERL_NIF_TERM trace(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    int state_arity;
    ErlNifPid self, to;
    ERL_NIF_TERM *tuple, msg;
    ASSERT(argc == 5);

    tuple = enif_alloc(sizeof(ERL_NIF_TERM)*(argc+1));
    memcpy(tuple+1,argv,sizeof(ERL_NIF_TERM)*argc);

    if (enif_self(env, &self)) {
        tuple[0] = enif_make_pid(env, &self);
    } else {
        tuple[0] = enif_make_atom(env, "undefined");
    }

    msg = enif_make_tuple_from_array(env, tuple, argc + 1);
    enif_get_local_pid(env, argv[1], &to);
    enif_send(env, &to, NULL, msg);
    enif_free(tuple);

    return atom_ok;
}
Exemplo n.º 6
0
static ERL_NIF_TERM GetPid(ErlNifEnv *env,
    int argc,
    const ERL_NIF_TERM argv[]) {
  TRACE("GetPid\n");
  return enif_make_pid(env, &server);
}
Exemplo n.º 7
0
// takes the first term off of the lua stack and return it as an
// erlang term in the state 'env'.
static int terminator_toerl_core(lua_State* lua, ERL_NIF_TERM *result, ErlNifEnv* env, ErlNifResourceType* resource_type)
{
	const int top = lua_gettop(lua);

	switch(lua_type(lua, top))
	{
		case LUA_TNIL:
		{
			*result = enif_make_atom(env, "nil");
			lua_pop( lua, 1);
			assert(lua_gettop(lua) == top-1);
			return 1;
			break;
		}
		case LUA_TNUMBER:
		{
			const lua_Number number = luaL_checknumber(lua, top);

			if(is_int64(number))
			{
				*result = enif_make_int64(env, (int64_t)number);
			}
			else
			{
				*result = enif_make_double(env, (double)number);
			}

			lua_pop( lua, 1);
			assert(lua_gettop(lua) == top-1);
			return 1;
			break;
		}
		case LUA_TBOOLEAN:
		{
			const int truefalse = lua_toboolean(lua, top);
			*result = truefalse ? enif_make_atom(env, "true") : enif_make_atom(env, "false");
			lua_pop( lua, 1);
			assert(lua_gettop(lua) == top-1);
			return 1;
			break;
		}
		case LUA_TSTRING:
		{
			// get the lua string
			size_t string_len;
			const char * lua_string = lua_tolstring (lua, top, &string_len);

			// make space in erlang for it
			ErlNifBinary binary;
			if(enif_alloc_binary(string_len, &binary))
			{
				// clean it
				memset(binary.data, 0, binary.size);

				// copy it over
				memcpy(binary.data, lua_string, string_len);

				*result = enif_make_binary(env, &binary);
			}
			else
			{
				luaL_error (lua, "could not convert lua string");
			}
			lua_pop( lua, 1);

			assert(lua_gettop(lua) == top-1);
			return 1;
			break;
		}
		case LUA_TTABLE:
		{
			size_t table_size = 0;

			int is_array = lua_is_array(lua);

			// table is at the top of the stack
			lua_pushnil(lua);  // nil as the first key
			while (lua_next(lua, top) != 0) {
				++table_size;
				lua_pop(lua, 1);
			}

			// make sure we can grow the stack
			luaL_checkstack(lua, 2, ERROR_STACK_MESSAGE);

			ERL_NIF_TERM *new_table = (ERL_NIF_TERM*) node_alloc(table_size * sizeof(ERL_NIF_TERM));
			ERL_NIF_TERM *next_cell = new_table;

			// table is at the top of the stack
			lua_pushnil(lua);  // nil as the first key
			while (lua_next(lua, top) != 0) 
			{
				// uses 'key' (at index -2) and 'value' (at index -1)
				if(is_array)
				{
					// remove 'value', keeps 'key' for next iteration
					ERL_NIF_TERM value;
					terminator_toerl_core(lua, &value, env, resource_type);
					*next_cell = value;
				}
				else
				{					
					// remove 'value', keeps 'key' for next iteration
					ERL_NIF_TERM tuple_value;
					terminator_toerl_core(lua, &tuple_value, env, resource_type);

					ERL_NIF_TERM tuple_key;
					lua_pushvalue( lua, -1);
					terminator_toerl_core(lua, &tuple_key, env, resource_type);

					*next_cell = enif_make_tuple2(env, tuple_key, tuple_value);
				}				

				next_cell++;
			}

			if(NULL != new_table)
			{
				*result = enif_make_list_from_array(env, new_table, table_size);
				node_free(new_table);
			}

			lua_pop( lua, 1);
			assert(lua_gettop(lua) == top-1);
			return 1;
			break;
		}
		case LUA_TUSERDATA:
		{
			// add metatable to stack
			if(lua_getmetatable (lua, top))
			{

				// put the pid metatable onto the stack
				// compare the two metatables
				luaL_getmetatable(lua, TYPE_ERL_PID);
				if(lua_compare(lua, -1, -2, LUA_OPEQ))
				{
					const ErlNifPid* userdata = (const ErlNifPid*) lua_touserdata(lua, top);
					*result = enif_make_pid(env, userdata);
					lua_pop(lua, 3);
					assert(lua_gettop(lua) == top-1);
					return 1;
				}
				// pop the pid metatable
				lua_pop(lua, 1);			
				
				// push the ref metatable
				luaL_getmetatable(lua, TYPE_ERL_REF);
				if(lua_compare(lua, -1, -2, LUA_OPEQ))
				{
					erlref_ptr erlref = (erlref_ptr) lua_touserdata(lua, top);
					*result = enif_make_copy( env, erlref->reference );
					lua_pop(lua, 3);
					assert(lua_gettop(lua) == top-1);
					return 1;
				}
				lua_pop(lua, 1);

				// pop the ref metatable
				luaL_getmetatable(lua, TYPE_LUA_ADDRESS);
				if(lua_compare(lua, -1, -2, LUA_OPEQ))
				{
					mailbox_address_ptr address = (mailbox_address_ptr) lua_touserdata(lua, top);

					assert(NULL != address);
					state_work_ptr state_work = address->state_work;
					assert(NULL != state_work);
					void* resource;
					(*result) = state_make_resource( env, &resource, resource_type, state_work, WEAK_REF);
					assert(NULL != resource);
					lua_pop(lua, 3);

					assert(lua_gettop(lua) == top-1);
					return 1;
				}

				// pop the metatable
				lua_pop(lua, 1);
			}

			lua_pop( lua, 2);
			*result = enif_make_atom(env, "unknown_lua_userdata");
			
			assert(lua_gettop(lua) == top-1);
			return 1;
			break;
		}
		case LUA_TLIGHTUSERDATA:
		{
			*result = enif_make_atom(env, "lua_lightuserdata_notsupported");
			lua_pop(lua, 1);
			assert(lua_gettop(lua) == top-1);
			return 1;
			break;
		}
		case LUA_TTHREAD:
		{
			*result = enif_make_atom(env, "lua_thread_notsupported");
			lua_pop(lua, 1);
			assert(lua_gettop(lua) == top-1);
			return 1;
			break;
		}
		case LUA_TFUNCTION:
		{
			*result = enif_make_atom(env, "lua_function_notsupported");
			lua_pop(lua, 1);
			assert(lua_gettop(lua) == top-1);
			return 1;
			break;
		}
	}
	assert(lua_gettop(lua) == top-1);
	return 0;
}
Exemplo n.º 8
0
static ERL_NIF_TERM make_term_caller_pid(struct make_term_info* mti, int n)
{
    ErlNifPid pid;    
    return enif_make_pid(mti->dst_env, enif_self(mti->caller_env, &pid));    		
}