/* * Sequence number generator. */ Class SeqGenerator { Const SHM_KEY = 1; /** * Initialize the sequence number generator. * This method is valid only when it is called for the first time after the server is started. * @ Param int $ start generates the starting value of the sequence number. * @ Return boolean true indicates success. */ Static public function init ($ start = 1) { // Mutex through semaphores to avoid access conflicts to the shared memory $ Sw = new SemWrapper; If (! $ Sw-> acquire ()){ Return false; } // Enable shared memory $ Shm_id = shmop_open (self: SHM_KEY, 'n', 0644, 4 ); If (empty ($ shm_id )){ // Because the 'N' mode is used, if you cannot enable the shared memory, you can think that the shared memory has been created and you do not need to initialize it again. $ Sw-> release (); Return true; } // Write the initial value to the shared memory $ Size = shmop_write ($ shm_id, pack ('l', $ start), 0 ); If ($ size! = 4 ){ Shmop_close ($ shm_id ); $ Sw-> release (); Return false; } // Disable shared memory and release semaphores Shmop_close ($ shm_id ); $ Sw-> release (); Return true; } /** * Generate the next sequence number. * @ Return int indicates the sequence number generated. */ Static public function next () { // Mutex through semaphores to avoid access conflicts to the shared memory $ Sw = new SemWrapper; If (! $ Sw-> acquire ()){ Return 0; } // Enable shared memory $ Shm_id = shmop_open (self: SHM_KEY, 'w', 0, 0 ); If (empty ($ shm_id )){ $ Sw-> release (); Return 0; } // Read the sequence number from the shared memory $ Data = shmop_read ($ shm_id, 0, 4 ); If (empty ($ data )){ $ Sw-> release (); Return 0; } $ Arr = unpack ('l', $ data ); $ Seq = $ arr [1]; // Write the next sequence number to the shared memory $ Size = shmop_write ($ shm_id, pack ('l', $ seq + 1), 0 ); If ($ size! = 4 ){ $ Sw-> release (); Return 0; } // Disable shared memory and release semaphores Shmop_close ($ shm_id ); $ Sw-> release (); Return $ seq; } } |