Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Need help with enif_select() #1

Open
rushikesh1 opened this issue Jul 18, 2019 · 2 comments
Open

Need help with enif_select() #1

rushikesh1 opened this issue Jul 18, 2019 · 2 comments

Comments

@rushikesh1
Copy link

I am trying to write a code in nif which will work asynchronously.

For that I am referring code for tcp server code for normal select() (refer link https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/tcpserver.c)
I wrapped this code in a function say listen() and invoked it in a erlang function start() as shown in below snippet

This start() has two process spawned
spawn(server, listen, [3]),
spawn(server, say_something, [goodbye, 3]).

And as per my expectation I want say_something() to be executed in parallel with listen(). For this I replaced select() call in tcpserver.c with enif_select() as below

ERL_NIF_TERM temp;
ERL_NIF_TERM atom_undefined;
 ErlNifResourceTypeInit rt_init = {NULL, ttsl_rt_stop};
 ttsl_resource_type = enif_open_resource_type_x(env, "tty_sl", &rt_init,
                                               ERL_NIF_RT_CREATE, NULL);
ttsl_resource = enif_alloc_resource(ttsl_resource_type, sizeof(struct ttsl_resource_t));
enif_select(env, parentfd, ERL_NIF_SELECT_WRITE, ttsl_resource, NULL, atom_undefined);

But this code is not working as expected and it is generating core in scheduler. Can you please guide me with this ?
Please let me know If you want me to share complete code.


-module(server).
-export([foo/1,start/0, say_something/2]).
-on_load(init/0).

init() ->
ok = erlang:load_nif("./tcpserver", 0).

listen(_X) ->
exit(nif_library_not_loaded).

say_something(What, 0) ->
done;
say_something(What, Times) ->
io:format("pn", [What]),
say_something(What, Times - 1).

start() ->
spawn(server, listen, [3]),
spawn(server, say_something, [goodbye, 3]).

@potatosalad
Copy link
Owner

@rushikesh1 Could you provide a gist or a repository where I can see the complete code?

@rushikesh1
Copy link
Author

Hi @potatosalad . Sorry for trouble and late response.

Here is gist for code https://gist.github.com/rushikesh1/e351af7800be91a564481c81e32df1dd

I have slightly modified your code and I am able to run it on unix but I am still facing issues on Windows. enif_select() is not working for me in case of windows.

I have made few changes in your code. In connect_nif() I am creating a ListenSocket for windows similar to what you did for unix. And in recv_try_nif() I am accepting new connections on this ListenSocket.
Once I get clientSocket I wanted to pass this socket back to erlang module for performing further read/write on this socket. But currently I am doing read/write in same recv_try_nif() .

The problem I am facing is the sverk_tcp_nif.erl is not recieving {select, Rsrc, Ref, ready_input} though there is new connections recived on ListenSocket which is passed to nif_select() .

Can you please let me know what am I missing in case of windows ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants