In reply to shaygueta:
Just fork the timeout delay.
task automatic timeout(ref logic signal,input logic value,input time timeout_value);
bit timed_out;
fork begin
fork
begin
#timeout_value;
`uvm_error(....
timed_out = '1;
end
join_none
wait(signal === value || timed_out);
disable fork;
end join
endtask
Note the enclosing fork/join is needed to prevent the disable fork from killing other child threads that may have been spawned before calling this task.