onepub-dev / dcli

An extensive library and tooling for building console/cli applications and scripts using the Dart programming language.
244 stars 28 forks source link

dcli compile broken on mac os #253

Open bsutton opened 1 month ago

bsutton commented 1 month ago

Hi, I have same problem. dcli version is 6.0.5 and dart 3.4.3, on macos arm64

ArgumentError: Invalid argument(s): Couldn't resolve native function 'pthread_mutex_timedlock' in 'package:native_synchronization_temp/src/bindings/pthread.dart' : No asset with id 'package:native_synchronization_temp/src/bindings/pthread.dart' found. No available native assets. Attempted to fallback to process lookup. dlsym(RTLD_DEFAULT, pthread_mutex_timedlock): symbol not found.

This problem also affects and dcli function that uses withNamedLockAsync

bsutton commented 1 month ago

@bsutton The solution seems to be to provide a custom implementation of the pthread_mutex_timedlock function. I'm making some tries editing directly the pub content.

I don't known low level details so with the help of chatgpt I replaced pthread_mutex_timedlock function in native_synchronization_temp/lib/src/bindings/pthread.dart with:

/// at the top, add another import import 'package:ffi/ffi.dart';

/// Constants (maybe we should get these values in another way, currently hard coded) const int EBUSY = 16; // Resource busy const int ETIMEDOUT = 60; // Operation timed out const int CLOCK_REALTIME = 0;

/// Bind the clock_gettime function from the C library final clock_gettime = DynamicLibrary.process().lookupFunction< Int32 Function(Int32 clockId, Pointer tp), int Function(int clockId, Pointer tp)>('clock_gettime');

/// Mutex lock implementation for macOS int pthread_mutex_timedlock( Pointer mutex, Pointer abstime) { final pthreadMutexTryLock = DynamicLibrary.process().lookupFunction< Int Function(Pointer), int Function(Pointer)>('pthread_mutex_trylock');

final nanosleep = DynamicLibrary.process().lookupFunction< Int Function( Pointer req, Pointer rem), int Function(Pointer req, Pointer rem)>('nanosleep');

final timeout = abstime.ref; final now = malloc(); final remainingTime = malloc();

while (true) { final ret = pthreadMutexTryLock(mutex); if (ret == 0) { malloc.free(now); malloc.free(remainingTime); return 0; } else if (ret != EBUSY) { malloc.free(now); malloc.free(remainingTime); return ret; }

clock_gettime(CLOCK_REALTIME, now);

if (now.ref.tv_sec > timeout.tv_sec ||
    (now.ref.tv_sec == timeout.tv_sec &&
        now.ref.tv_nsec >= timeout.tv_nsec)) {
  malloc.free(now);
  malloc.free(remainingTime);
  return ETIMEDOUT;
}

remainingTime.ref.tv_sec = timeout.tv_sec - now.ref.tv_sec;
remainingTime.ref.tv_nsec = timeout.tv_nsec - now.ref.tv_nsec;
if (remainingTime.ref.tv_nsec < 0) {
  remainingTime.ref.tv_sec -= 1;
  remainingTime.ref.tv_nsec += 1000000000;
}

nanosleep(remainingTime, nullptr);

} } Now the cli works, I have tried with a 'some command'.run (that previously didn't work)

I don't know if the provided code is a right mock implementation of the pthread_mutex_timedlock.

bsutton commented 1 month ago

And now I've just read your updated comment and realised what the code was for.

So you are saying that macos is missing the pthread_mutex_timedlock. That puts quite a different shade on the problem.

So I don't have time now but I will look at the practicalities of integrating your mutex code into the library.

At a quick look I don't think the chat gpt implementation is correct.

This link proposes a solution:

https://lists.apache.org/thread/yqdnsky6svc5cfdkx1s8m4d3j8h9xyj6

edit: updated link

bsutton commented 1 month ago

So, the issue is more related to native_synchronization_temp/native_synchronization?

bsutton commented 1 month ago

@danieletulone I'm heavily committed this week, If you have time to look at the above link and raise a PR it would be appreciated.