github.com/gogf/gf@v1.16.9/os/gmutex/gmutex_unit_test.go (about)

     1  // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the MIT License.
     4  // If a copy of the MIT was not distributed with this file,
     5  // You can obtain one at https://github.com/gogf/gf.
     6  
     7  package gmutex_test
     8  
     9  import (
    10  	"github.com/gogf/gf/os/glog"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/gogf/gf/container/garray"
    15  	"github.com/gogf/gf/os/gmutex"
    16  	"github.com/gogf/gf/test/gtest"
    17  )
    18  
    19  func Test_Mutex_RUnlock(t *testing.T) {
    20  	gtest.C(t, func(t *gtest.T) {
    21  		mu := gmutex.New()
    22  		for index := 0; index < 1000; index++ {
    23  			go func() {
    24  				mu.RLockFunc(func() {
    25  					time.Sleep(200 * time.Millisecond)
    26  				})
    27  			}()
    28  		}
    29  		time.Sleep(100 * time.Millisecond)
    30  		t.Assert(mu.IsRLocked(), true)
    31  		t.Assert(mu.IsLocked(), true)
    32  		t.Assert(mu.IsWLocked(), false)
    33  		for index := 0; index < 1000; index++ {
    34  			go func() {
    35  				mu.RUnlock()
    36  			}()
    37  		}
    38  		time.Sleep(300 * time.Millisecond)
    39  		t.Assert(mu.IsRLocked(), false)
    40  
    41  	})
    42  
    43  	//RLock before Lock
    44  	gtest.C(t, func(t *gtest.T) {
    45  		mu := gmutex.New()
    46  		mu.RLock()
    47  		go func() {
    48  			mu.Lock()
    49  			time.Sleep(300 * time.Millisecond)
    50  			mu.Unlock()
    51  		}()
    52  		time.Sleep(100 * time.Millisecond)
    53  		mu.RUnlock()
    54  		t.Assert(mu.IsRLocked(), false)
    55  		time.Sleep(100 * time.Millisecond)
    56  		t.Assert(mu.IsLocked(), true)
    57  		time.Sleep(400 * time.Millisecond)
    58  		t.Assert(mu.IsLocked(), false)
    59  	})
    60  }
    61  
    62  func Test_Mutex_IsLocked(t *testing.T) {
    63  	gtest.C(t, func(t *gtest.T) {
    64  		mu := gmutex.New()
    65  		go func() {
    66  			mu.LockFunc(func() {
    67  				time.Sleep(200 * time.Millisecond)
    68  			})
    69  		}()
    70  		time.Sleep(100 * time.Millisecond)
    71  		t.Assert(mu.IsLocked(), true)
    72  		t.Assert(mu.IsWLocked(), true)
    73  		t.Assert(mu.IsRLocked(), false)
    74  		time.Sleep(300 * time.Millisecond)
    75  		t.Assert(mu.IsLocked(), false)
    76  		t.Assert(mu.IsWLocked(), false)
    77  
    78  		go func() {
    79  			mu.RLockFunc(func() {
    80  				time.Sleep(200 * time.Millisecond)
    81  			})
    82  		}()
    83  		time.Sleep(100 * time.Millisecond)
    84  		t.Assert(mu.IsRLocked(), true)
    85  		t.Assert(mu.IsLocked(), true)
    86  		t.Assert(mu.IsWLocked(), false)
    87  		time.Sleep(300 * time.Millisecond)
    88  		t.Assert(mu.IsRLocked(), false)
    89  	})
    90  }
    91  
    92  func Test_Mutex_Unlock(t *testing.T) {
    93  	gtest.C(t, func(t *gtest.T) {
    94  		mu := gmutex.New()
    95  		array := garray.New(true)
    96  		go func() {
    97  			mu.LockFunc(func() {
    98  				array.Append(1)
    99  				time.Sleep(300 * time.Millisecond)
   100  			})
   101  		}()
   102  		go func() {
   103  			time.Sleep(100 * time.Millisecond)
   104  			mu.LockFunc(func() {
   105  				array.Append(1)
   106  			})
   107  		}()
   108  		go func() {
   109  			time.Sleep(100 * time.Millisecond)
   110  			mu.LockFunc(func() {
   111  				array.Append(1)
   112  			})
   113  		}()
   114  
   115  		go func() {
   116  			time.Sleep(200 * time.Millisecond)
   117  			mu.Unlock()
   118  			mu.Unlock()
   119  			mu.Unlock()
   120  			mu.Unlock()
   121  		}()
   122  
   123  		time.Sleep(100 * time.Millisecond)
   124  		t.Assert(array.Len(), 1)
   125  		time.Sleep(400 * time.Millisecond)
   126  		t.Assert(array.Len(), 3)
   127  	})
   128  }
   129  
   130  func Test_Mutex_LockFunc(t *testing.T) {
   131  	gtest.C(t, func(t *gtest.T) {
   132  		mu := gmutex.New()
   133  		array := garray.New(true)
   134  		go func() {
   135  			mu.LockFunc(func() {
   136  				array.Append(1)
   137  				time.Sleep(300 * time.Millisecond)
   138  			})
   139  		}()
   140  		go func() {
   141  			time.Sleep(100 * time.Millisecond)
   142  			mu.LockFunc(func() {
   143  				array.Append(1)
   144  			})
   145  		}()
   146  		time.Sleep(100 * time.Millisecond)
   147  		t.Assert(array.Len(), 1)
   148  		time.Sleep(100 * time.Millisecond)
   149  		t.Assert(array.Len(), 1)
   150  		time.Sleep(200 * time.Millisecond)
   151  		t.Assert(array.Len(), 2)
   152  	})
   153  }
   154  
   155  func Test_Mutex_TryLockFunc(t *testing.T) {
   156  	gtest.C(t, func(t *gtest.T) {
   157  		mu := gmutex.New()
   158  		array := garray.New(true)
   159  		go func() {
   160  			mu.LockFunc(func() {
   161  				array.Append(1)
   162  				time.Sleep(300 * time.Millisecond)
   163  			})
   164  		}()
   165  		go func() {
   166  			time.Sleep(100 * time.Millisecond)
   167  			mu.TryLockFunc(func() {
   168  				array.Append(1)
   169  			})
   170  		}()
   171  		go func() {
   172  			time.Sleep(400 * time.Millisecond)
   173  			mu.TryLockFunc(func() {
   174  				array.Append(1)
   175  			})
   176  		}()
   177  		time.Sleep(100 * time.Millisecond)
   178  		t.Assert(array.Len(), 1)
   179  		time.Sleep(100 * time.Millisecond)
   180  		t.Assert(array.Len(), 1)
   181  		time.Sleep(300 * time.Millisecond)
   182  		t.Assert(array.Len(), 2)
   183  	})
   184  }
   185  
   186  func Test_Mutex_RLockFunc(t *testing.T) {
   187  	gtest.C(t, func(t *gtest.T) {
   188  		mu := gmutex.New()
   189  		array := garray.New(true)
   190  		go func() {
   191  			mu.LockFunc(func() {
   192  				array.Append(1)
   193  				time.Sleep(300 * time.Millisecond)
   194  			})
   195  		}()
   196  		go func() {
   197  			time.Sleep(100 * time.Millisecond)
   198  			mu.RLockFunc(func() {
   199  				array.Append(1)
   200  				time.Sleep(100 * time.Millisecond)
   201  			})
   202  		}()
   203  		time.Sleep(100 * time.Millisecond)
   204  		t.Assert(array.Len(), 1)
   205  		time.Sleep(100 * time.Millisecond)
   206  		t.Assert(array.Len(), 1)
   207  		time.Sleep(300 * time.Millisecond)
   208  		t.Assert(array.Len(), 2)
   209  	})
   210  
   211  	gtest.C(t, func(t *gtest.T) {
   212  		mu := gmutex.New()
   213  		array := garray.New(true)
   214  		go func() {
   215  			time.Sleep(100 * time.Millisecond)
   216  			mu.RLockFunc(func() {
   217  				array.Append(1)
   218  				time.Sleep(100 * time.Millisecond)
   219  			})
   220  		}()
   221  		go func() {
   222  			time.Sleep(100 * time.Millisecond)
   223  			mu.RLockFunc(func() {
   224  				array.Append(1)
   225  				time.Sleep(100 * time.Millisecond)
   226  			})
   227  		}()
   228  		go func() {
   229  			time.Sleep(100 * time.Millisecond)
   230  			mu.RLockFunc(func() {
   231  				array.Append(1)
   232  				time.Sleep(100 * time.Millisecond)
   233  			})
   234  		}()
   235  		t.Assert(array.Len(), 0)
   236  		time.Sleep(200 * time.Millisecond)
   237  		t.Assert(array.Len(), 3)
   238  	})
   239  }
   240  
   241  func Test_Mutex_TryRLockFunc(t *testing.T) {
   242  	gtest.C(t, func(t *gtest.T) {
   243  		var (
   244  			mu    = gmutex.New()
   245  			array = garray.New(true)
   246  		)
   247  		// First writing lock
   248  		go func() {
   249  			mu.LockFunc(func() {
   250  				array.Append(1)
   251  				glog.Println("lock1 done")
   252  				time.Sleep(2000 * time.Millisecond)
   253  			})
   254  		}()
   255  		// This goroutine never gets the lock.
   256  		go func() {
   257  			time.Sleep(1000 * time.Millisecond)
   258  			mu.TryRLockFunc(func() {
   259  				array.Append(1)
   260  			})
   261  		}()
   262  		for index := 0; index < 1000; index++ {
   263  			go func() {
   264  				time.Sleep(4000 * time.Millisecond)
   265  				mu.TryRLockFunc(func() {
   266  					array.Append(1)
   267  				})
   268  			}()
   269  		}
   270  		time.Sleep(1000 * time.Millisecond)
   271  		t.Assert(array.Len(), 1)
   272  		time.Sleep(1000 * time.Millisecond)
   273  		t.Assert(array.Len(), 1)
   274  		time.Sleep(1000 * time.Millisecond)
   275  		t.Assert(array.Len(), 1)
   276  		time.Sleep(2000 * time.Millisecond)
   277  		t.Assert(array.Len(), 1001)
   278  	})
   279  }