I'm going to assume that you mean interrupts, even though interrupt handlers in kernels usually have much more special limitations. The same argument applies to signal handlers, but it's usually simpler than the special restrictions on interrupt handlers. In case my assumption is wrong just replace "interrupt" with "signal" in the answer and it will apply.
Functions can be thread-safe without being signal/interrupt safe. If the function protects its internal state with a lock and then holds that lock when getting an interrupt there is no way for the interrupt handler to acquire that lock since the execution path that holds the lock is blocked by the interrupt. To release the lock you'd have to exit from the interrupt handler, resume execution of the thread until the lock is released and then go back to the interrupt handler. This is typically not really doable unless your kernel has implemented interrupt handlers as threads that can yield execution when waiting for locks.
A normal way to make a function both interrupt and thread safe is to block interrupts while holding the lock, but this is quite expensive and isn't done unless it's very necessary.