lk

package
v0.0.0-...-91c5940 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 16, 2017 License: GPL-3.0 Imports: 6 Imported by: 0

Documentation

Index

Constants

View Source
const (
	SPEC_DEFAULT_REG_DBRESLIST_CAPACITY  = 6
	SPEC_DEFAULT_REG_OBJRESLIST_CAPACITY = 10
)
View Source
const (
	TYPE_DB_LOCK     lock_type_t = 1
	TYPE_OBJECT_LOCK lock_type_t = 2
)
View Source
const (
	ANSWER_TIMEOUT                  answer_t = iota + 1 // Lock() function returns this value if timeout occured
	ANSWER_REQUESTED_LOCKS_ACQUIRED                     // Lock() function returns this value if all requested locks have been acquired

)
View Source
const SPEC_CHANNEL_DEFAULT_LENGTH = 64 // because there is at most 64 workers
View Source
const SPEC_LOCK_MANAGER_MAP_DEFAULT_SIZE = 20

Variables

This section is empty.

Functions

This section is empty.

Types

type Dbres_list

type Dbres_list []Dbres_list_elem

list of database names, and requested locks.

type Dbres_list_elem

type Dbres_list_elem struct {
	Db_name string // database name

	Permissions_required rsql.Permission_t // This field IS NOT USED by the lock manager. It contains permissions required to work on the database, PERMISSION_SELECT/INSERT/UPDATE/DELETE/MODIFY_DATABASE/MODIFY_PRINCIPAL/MODIFY_OBJECT
	// contains filtered or unexported fields
}

list of requested and already acquired locks on databases.

type Diagnostic

type Diagnostic struct {
	// contains filtered or unexported fields
}

type Lock_manager

type Lock_manager struct {
	// contains filtered or unexported fields
}

Lock_manager is mainly a map, with db or object name as key, and each entry pointing to a lock_element.

var G_LOCK_MANAGER Lock_manager

global lock manager object

func (*Lock_manager) Acquire

func (lockmgr *Lock_manager) Acquire(registration *Registration) *rsql.Error

Acquire acquires all requested locks in Registration, or times out.

In case of timeout, an error is returned.

If you have called Acquire(), then you must always call Release() to free the lock elements.

The call sequence is:

  • registration.Register_object(...) or registration.Register_db(...)

  • (Register method is called multiple time to register all requested locks)

  • if rsql_err := G_LOCK_MANAGER.Acquire(registration); rsql_err != nil { return rsql_err }

  • (do your stuff)

  • registration.Register_object(...) or registration.Register_db(...) more locks can be requested

  • (Register method is called multiple time to register all requested locks)

  • if rsql_err := G_LOCK_MANAGER.Acquire(registration); rsql_err != nil { return rsql_err }

  • (do your stuff)

  • G_LOCK_MANAGER.Release(registration)

If the locks are successfully acquired, lock entries in Registration object are modified from requested to acquired. In case of timeout, Registration object is not modified. In particular, locks already acquired are kept this way. So, it is safer to always call Release(), also if you received a timeout error.

Acquire can be called multiple times. If all locks in Registration are already acquired, the function does nothing.

func (*Lock_manager) Debug_print

func (lockmgr *Lock_manager) Debug_print()

for debugging only. WARNING: not thread-safe. If called outside of the lock manager code, it is possible that locks are being acquired or released.

Reading lockmgr.lmgr_hashtable when the lock manager is possibly modifying it is no safe and a crash is possible.

func (*Lock_manager) Get_locks_list

func (lockmgr *Lock_manager) Get_locks_list(worker_id uint32) []string

Get_locks_list gets the list of all locks in the lock manager.

func (*Lock_manager) Initialize

func (lockmgr *Lock_manager) Initialize(ticker_interval time.Duration, timeout_ticks_count uint64)

func (*Lock_manager) Release

func (lockmgr *Lock_manager) Release(registration *Registration)

Release frees all locks in Registration, and release lock objects. After the call, Registration object is empty. It can be called many times, but subsequent calls just do nothing as Registration object is empty.

type Lock_t

type Lock_t int8

Lock type are only LOCK_SHARED (database is being used, or table is being read), or LOCK_EXCLUSIVE (database is created or deleted, or table is created, written to, deleted).

  • LOCK_EXCLUSIVE: only one worker can have this lock
  • LOCK_SHARED: many workers can have this lock at the same time.

LOCK_EXCLUSIVE and LOCK_SHARED are mutually incompatible.

NOTE: when a table is LOCK_EXCLUSIVE, the database is usually LOCK_SHARED. A database needs LOCK_EXCLUSIVE only when it is created, deleted, or backed up.

const (
	LOCK_SHARED    Lock_t = 1 // note that the expression    LOCK_SHARED < LOCK_EXCLUSIVE         is used in the code. So, don't change these constant values !
	LOCK_EXCLUSIVE Lock_t = 2
)

func (Lock_t) String

func (l Lock_t) String() string

type Locking_capability_t

type Locking_capability_t uint8

Returned value from check_locks() function.

   Locks are reserved or acquired in all-or-none manner.
   Locks must be reserved before being acquired. But if they can be reserved and also acquired, reservation step is skipped.

	  LOCKING_CAPABILITY_NONE:     impossible to reserve the requested locks. The worker must wait.
	  LOCKING_CAPABILITY_RESERVE:  impossible to acquire the requested locks. The locks are reserved and the worker must wait.
	  LOCKING_CAPABILITY_ACQUIRE:  locks have been acquired. The worker can go on.
const (
	LOCKING_CAPABILITY_NONE    Locking_capability_t = 0
	LOCKING_CAPABILITY_RESERVE Locking_capability_t = 1
	LOCKING_CAPABILITY_ACQUIRE Locking_capability_t = 2
)

func (Locking_capability_t) String

func (lc Locking_capability_t) String() string

type Objres_list

type Objres_list []Objres_list_elem

list of object names, and requested locks.

type Objres_list_elem

type Objres_list_elem struct {
	Db_name     string
	Schema_name string
	Object_name string

	Permissions_required rsql.Permission_t // This field IS NOT USED by the lock manager. It contains only the four permissions required to work on the data of the object, PERMISSION_SELECT/INSERT/UPDATE/DELETE
	// contains filtered or unexported fields
}

list of requested and already acquired locks on objects.

type Registration

type Registration struct {
	Reg_dbreslist  Dbres_list
	Reg_objreslist Objres_list
	// contains filtered or unexported fields
}

Registration is a list of databases and objects that the worker wants to lock.

When the worker wants to acquire all requested locks in Registration:

  • it passes the Registration object to the lock manager, and waits.
  • the lock manager will reserve and acquire all requested locks, and then return to the worker the Registration with all locks acquired.
  • the worker wakes up and can resume its activity

Lock states are:

  • requested, but not reserved
  • requested and reserved
  • acquired

func New_registration

func New_registration(worker_id uint32) *Registration

func (*Registration) Debug_print

func (registration *Registration) Debug_print()

func (*Registration) Register_db

func (registration *Registration) Register_db(db_name string, lock Lock_t, permission rsql.Permission_t)

Register_db enlists a database name in the Registration. If database name already exists in Registration, requested lock type may be upgraded (LOCK_SHARED->LOCK_EXCLUSIVE) if needed, else nothing is done. There is no database name duplicate.

Permission is used to implement the database READ_ONLY mode. Permissions will accumulate in the database entry in Registration. You will pass PERMISSION_MODIFY_DATABASE/MODIFY_PRINCIPAL/MODIFY_OBJECT. The function Register_object can pass PERMISSION_SELECT/INSERT/UPDATE/DELETE.

func (*Registration) Register_object

func (registration *Registration) Register_object(db_name string, schema_name string, object_name string, lock Lock_t, permission rsql.Permission_t)

Register_db enlists an object name in the Registration. If object name already exists in Registration, requested lock type may be upgraded (LOCK_SHARED->LOCK_EXCLUSIVE) if needed, else nothing is done. There is no object name duplicate.

This function also registers the database name for LOCK_SHARED (when working on objects, there is no need to put LOCK_EXCLUSIVE on the database).

Permission is used to implement the database READ_ONLY mode. Permissions will accumulate in the database entry in Registration. You will pass PERMISSION_MODIFY_OBJECT/SELECT/INSERT/UPDATE/DELETE.

Permission is also used to check if the user has all needed permissions to work on the object.

func (*Registration) Register_object_qname

func (registration *Registration) Register_object_qname(qname rsql.Object_qname_t, lock Lock_t, permission rsql.Permission_t)

Register_object_qname is same as Register_object, but takes rsql.Object_qname_t as argument.

type Waiting_queue

type Waiting_queue []*Registration

func (*Waiting_queue) Delete

func (q *Waiting_queue) Delete(i int)

func (*Waiting_queue) Delete_nil_entries

func (q *Waiting_queue) Delete_nil_entries()

func (*Waiting_queue) Insert_last

func (q *Waiting_queue) Insert_last(reg *Registration)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL