Question: It is a .Net application which works with an external device. When some entity (corresponds to the row in a table) wants to communicate with device, the corresponding row in the SQL Server table should be locked until the device return a result or SQL Server times out.

I need to: 

* lock a specific row in a table so that row could be read, but could not be deleted or updated.
* locking mechanism should run in a separate thread so that application's main thread works as usual
* lock should be released if a response has made
* lock should be released after a while if no response is received

What is the best practice? 

Is there any standardize way to accomplish this?

Should I:

* run a new thread (task) in my C# code and begin a serializable transaction, select desired row transactionally and wait to either time is up or cancellation token is received?
* or use some combination of `sp_getapplock` and ...etc?

Answer: 
You could pass a `struct node**` as suggested by @sje397. 

However, I would suggest the following design (which, in my opinion is easier to reason about too):

```
/* returns the new head of the list */
struct node *insert (struct node* current_head, int x) {
    struct node* temp = (struct node*)malloc(sizeof(struct node));
    temp->data = x;
    temp->next = current_head;
    return temp;
}

```

and use it like

```
head = insert(head, 5);

```

In this case I would also rename the function something like `push_front`.

Just for completeness, I think @sje397 meant something like the following (Typical linked list code rewritten again and again by every C programmer...):

```
void insert(struct node **head, int x) {
    struct node* new_head = (struct node*)malloc(sizeof(struct node));
    new_head->data = x;
    new_head->next = *head;

    *head = new_head;
}

```
In C there is no pass by reference.  

Your insert function isn't inserting a node in the list, its just changing the node which the head points to. Because of `temp->next = NULL` the list will always contain two nodes.

Another error is that you're just modifying a local copy of the head node.
To fix this You have 3 choices:

-You can make the head node global

-You can pass a pointer to the head node(pointer to pointer) to the function.

-You can return the modified head node by the function.