Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 363265
b: refs/heads/master
c: c0f61a4
h: refs/heads/master
i:
  363263: 2f0623b
v: v3
  • Loading branch information
Erik Gilling authored and Greg Kroah-Hartman committed Mar 4, 2013
1 parent b36664c commit affae78
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 23 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 57b505bbe746dcc011152e79732bdaf96723c51a
refs/heads/master: c0f61a4e6145728153d0b94152b4dd5b06899b3b
46 changes: 31 additions & 15 deletions trunk/drivers/staging/android/sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -421,33 +421,22 @@ static void sync_fence_signal_pt(struct sync_pt *pt)
container_of(pos, struct sync_fence_waiter,
waiter_list);

waiter->callback(fence, waiter->callback_data);
list_del(pos);
kfree(waiter);
waiter->callback(fence, waiter);
}
wake_up(&fence->wq);
}
}

int sync_fence_wait_async(struct sync_fence *fence,
void (*callback)(struct sync_fence *, void *data),
void *callback_data)
struct sync_fence_waiter *waiter)
{
struct sync_fence_waiter *waiter;
unsigned long flags;
int err = 0;

waiter = kzalloc(sizeof(struct sync_fence_waiter), GFP_KERNEL);
if (waiter == NULL)
return -ENOMEM;

waiter->callback = callback;
waiter->callback_data = callback_data;

spin_lock_irqsave(&fence->waiter_list_lock, flags);

if (fence->status) {
kfree(waiter);
err = fence->status;
goto out;
}
Expand All @@ -459,6 +448,34 @@ int sync_fence_wait_async(struct sync_fence *fence,
return err;
}

int sync_fence_cancel_async(struct sync_fence *fence,
struct sync_fence_waiter *waiter)
{
struct list_head *pos;
struct list_head *n;
unsigned long flags;
int ret = -ENOENT;

spin_lock_irqsave(&fence->waiter_list_lock, flags);
/*
* Make sure waiter is still in waiter_list because it is possible for
* the waiter to be removed from the list while the callback is still
* pending.
*/
list_for_each_safe(pos, n, &fence->waiter_list_head) {
struct sync_fence_waiter *list_waiter =
container_of(pos, struct sync_fence_waiter,
waiter_list);
if (list_waiter == waiter) {
list_del(pos);
ret = 0;
break;
}
}
spin_unlock_irqrestore(&fence->waiter_list_lock, flags);
return ret;
}

int sync_fence_wait(struct sync_fence *fence, long timeout)
{
int err;
Expand Down Expand Up @@ -739,8 +756,7 @@ static void sync_print_fence(struct seq_file *s, struct sync_fence *fence)
container_of(pos, struct sync_fence_waiter,
waiter_list);

seq_printf(s, "waiter %pF %p\n", waiter->callback,
waiter->callback_data);
seq_printf(s, "waiter %pF\n", waiter->callback);
}
spin_unlock_irqrestore(&fence->waiter_list_lock, flags);
}
Expand Down
36 changes: 29 additions & 7 deletions trunk/drivers/staging/android/sync.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,10 @@ struct sync_fence {
struct list_head sync_fence_list;
};

struct sync_fence_waiter;
typedef void (*sync_callback_t)(struct sync_fence *fence,
struct sync_fence_waiter *waiter);

/**
* struct sync_fence_waiter - metadata for asynchronous waiter on a fence
* @waiter_list: membership in sync_fence.waiter_list_head
Expand All @@ -168,10 +172,15 @@ struct sync_fence {
struct sync_fence_waiter {
struct list_head waiter_list;

void (*callback)(struct sync_fence *fence, void *data);
void *callback_data;
sync_callback_t callback;
};

static inline void sync_fence_waiter_init(struct sync_fence_waiter *waiter,
sync_callback_t callback)
{
waiter->callback = callback;
}

/*
* API for sync_timeline implementers
*/
Expand Down Expand Up @@ -284,16 +293,29 @@ void sync_fence_install(struct sync_fence *fence, int fd);
/**
* sync_fence_wait_async() - registers and async wait on the fence
* @fence: fence to wait on
* @callback: callback
* @callback_data data to pass to the callback
* @waiter: waiter callback struck
*
* Returns 1 if @fence has already signaled.
*
* Registers a callback to be called when @fence signals or has an error
* Registers a callback to be called when @fence signals or has an error.
* @waiter should be initialized with sync_fence_waiter_init().
*/
int sync_fence_wait_async(struct sync_fence *fence,
void (*callback)(struct sync_fence *, void *data),
void *callback_data);
struct sync_fence_waiter *waiter);

/**
* sync_fence_cancel_async() - cancels an async wait
* @fence: fence to wait on
* @waiter: waiter callback struck
*
* returns 0 if waiter was removed from fence's async waiter list.
* returns -ENOENT if waiter was not found on fence's async waiter list.
*
* Cancels a previously registered async wait. Will fail gracefully if
* @waiter was never registered or if @fence has already signaled @waiter.
*/
int sync_fence_cancel_async(struct sync_fence *fence,
struct sync_fence_waiter *waiter);

/**
* sync_fence_wait() - wait on fence
Expand Down

0 comments on commit affae78

Please sign in to comment.