Nsv incr

From AOLserver Wiki
Jump to navigation Jump to search

Man page: http://aolserver.com/docs/tcl/nsv_incr.html


NAME

nsv_incr - Increment the value of the element in the nsv array arrayName specified by key

SYNOPSIS

nsv_incr arrayName key ?increment?

DESCRIPTION

If increment is supplied then its value (which must be an integer) is added to the value of the element key; otherwise 1 is added to the value of the element key. Unlike the TCL equivalent if key does not exists it is created. Returns the new value of the element specified by key. Internally interlocked so it is thread safe, no mutex required.

EXAMPLES

   % nsv_incr shared_array foo
   1
   % nsv_incr shared_array foo -1
   0

Is this a good implementation with behavior similar to using ns_mutex or ns_critsec, except that later threads do not wait for the first thread to exit the script?

What you're looking for is a kind of "ns_mutex trylock" type of functionality, where if the mutex is locked the caller doesn't block/sleep, but if it's unlocked, the caller locks the mutex. Interesting approach using NSVs, sure! -- Dossy 10:44, 27 June 2006 (EDT)
   # Return value 1 indicates that the call was executed normally
   # Return value 0 indicates that another thread was executing
   # the code so this thread was excluded
   
   proc write_special_file {data} {
       if {[nsv_incr one_thread_at_a_time $key] == 1} {
           set had_error [catch {
               set handle [open special_file w]
               puts $handle $data
               close $handle
           } message]
           nsv_set one_thread_at_a_time $key 0
           if {$had_error} {
               error $message
           }
           return 1
       } else {
           return 0
       }
   }
   
   proc read_special_file {result_varname} {
       if {[nsv_incr one_thread_at_a_time $key] == 1} {
           upvar $result_varname result
           set had_error [catch {
               set handle [open special_file r]
               set result [read $handle]
               close $handle
           } message]
           nsv_set one_thread_at_a_time $key 0
           if {$had_error} {
               error $message
           }
           return 1
       } else {
           return 0
       }
   }
   
   proc change_special_file {data result_varname} {
       if {[nsv_incr one_thread_at_a_time $key] == 1} {
           upvar $result_varname result
           # BOTH READ AND WRITE CALLS WILL DO NOTHING
           read_special_file result
           write_special_file $data
           nsv_set one_thread_at_a_time $key 0
           return 1
       } else {
           return 0
       }
   }

SEE ALSO

Thread-shared Variables