# Unlock the power of threadcall

**URL:** <https://discourse.julialang.org/t/unlock-the-power-of-threadcall/20882>\
**Category:** Internals & Design\
**Created:** [February 16, 2019, 10:48pm UTC](https://discourse.julialang.org/t/unlock-the-power-of-threadcall/20882 "2019-02-16T22:48:05Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![felipenoris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/felipenoris/32/553_2.png) [@felipenoris](https://discourse.julialang.org/u/felipenoris)\
**Post date:** [February 16, 2019, 10:48pm UTC](https://discourse.julialang.org/t/unlock-the-power-of-threadcall/20882/1 "2019-02-16T22:48:05Z")

</div>

Working on writing drivers for databases, I see that the threadcall macro would be a good fit for calling external C code that does IO operations.

After some testing, it looks like the macro does not support a common pattern that is to use a pointer handle as arguments in the C funcion.

Any info on what would it take to tackle this issue?

[https://github.com/JuliaLang/julia/issues/30864](https://github.com/JuliaLang/julia/issues/30864)

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [February 17, 2019, 12:20am UTC](https://discourse.julialang.org/t/unlock-the-power-of-threadcall/20882/2 "2019-02-17T00:20:56Z")

</div>

I’ve seen that issue and I originally implemented the threadcall macro but I must confess I don’t really get the issue. What is the error that happens? Is it cfunction that fails? Can’t you use a raw Ptr type instead of a Ref?

---

<div class="post-metadata">

**Author:** ![felipenoris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/felipenoris/32/553_2.png) [@felipenoris](https://discourse.julialang.org/u/felipenoris)\
**Post date:** [February 17, 2019, 5:36am UTC](https://discourse.julialang.org/t/unlock-the-power-of-threadcall/20882/3 "2019-02-17T05:36:43Z")

</div>

The error I get from a threadcall is:

```julia
ERROR: LoadError: argument is an abstract type; size is indeterminate.

```

After some debugging, I found out that this is happening because of the `Ref` arguments.

The API I’m calling makes use of output arguments.

So, in the example I posted, the C function expects a parameter of type `dpiConn **conn`, which is an output parameter.

Using pure C, the API would be called using:

```nohighlight
    dpiConn *conn;

    dpiConn_create(context, params->mainUserName,
            params->mainUserNameLength, params->mainPassword,
            params->mainPasswordLength, params->connectString,
            params->connectStringLength, NULL, NULL, &conn);

```

To mimic that in Julia, I use a `Ref{Ptr{Cvoid}}` argument to pass to `ccall`. Then I’ll retrieve the value returned by the C API using:

```julia
conn_handle_ref = Ref{Ptr{Cvoid}}()
... # call C api
return conn_handle_ref[] # return the handle.

```

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [February 17, 2019, 6:40am UTC](https://discourse.julialang.org/t/unlock-the-power-of-threadcall/20882/4 "2019-02-17T06:40:19Z")

</div>

Have you tried using Ptr instead of Ref?

---

<div class="post-metadata">

**Author:** ![felipenoris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/felipenoris/32/553_2.png) [@felipenoris](https://discourse.julialang.org/u/felipenoris)\
**Post date:** [February 17, 2019, 12:42pm UTC](https://discourse.julialang.org/t/unlock-the-power-of-threadcall/20882/5 "2019-02-17T12:42:26Z")

</div>

I might be missing some basic understanding on how `Ptr` works, but how am I supposed to use a `Ptr` argument as IN/OUT parameter under these conditions?

The function call is this:

```julia
conn_handle_ref = Ref{Ptr{Cvoid}}()
ora_common_params = OraCommonCreateParams(ctx, common_params)
ora_conn_create_params = OraConnCreateParams(ctx, conn_create_params)
result = dpiConn_create(ctx.handle, user, password, connect_string, Ref(ora_common_params), Ref(ora_conn_create_params), conn_handle_ref)
error_check(ctx, result)

my_new_connection = Connection(ctx, conn_handle_ref[], conn_create_params.pool)

```

Where

```julia
function dpiConn_create(context_handle::Ptr{Cvoid}, user::String, password::String, connect_string::String, common_params_ref::Ref{OraCommonCreateParams}, conn_create_params_ref::Ref{OraConnCreateParams}, dpi_conn_handle_ref::Ref{Ptr{Cvoid}})
    userNameLength = sizeof(user)
    passwordLength = sizeof(password)
    connectStringLength = sizeof(connect_string)

    ccall((:dpiConn_create, libdpi), OraResult, (Ptr{Cvoid}, Ptr{UInt8}, UInt32, Ptr{UInt8}, UInt32, Ptr{UInt8}, UInt32, Ref{OraCommonCreateParams}, Ref{OraConnCreateParams}, Ref{Ptr{Cvoid}}), context_handle, user, userNameLength, password, passwordLength, connect_string, connectStringLength, common_params_ref, conn_create_params_ref, dpi_conn_handle_ref)
end

```

and the C function definition is

```nohighlight
int dpiConn_create(const dpiContext *context, const char *userName, uint32_t userNameLength, const char *password, uint32_t passwordLength, const char *connectString, uint32_t connectStringLength, dpiCommonCreateParams *commonParams, dpiConnCreateParams *createParams, dpiConn **conn)

```
